| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 1 | //===------ SemaDeclCXX.cpp - Semantic Analysis for C++ Declarations ------===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
 | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | //  This file implements semantic analysis for C++ declarations. | 
 | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
| John McCall | 2d88708 | 2010-08-25 22:03:47 +0000 | [diff] [blame] | 14 | #include "clang/Sema/SemaInternal.h" | 
| Argyrios Kyrtzidis | a4755c6 | 2008-08-09 00:58:37 +0000 | [diff] [blame] | 15 | #include "clang/AST/ASTConsumer.h" | 
| Douglas Gregor | e37ac4f | 2008-04-13 21:30:24 +0000 | [diff] [blame] | 16 | #include "clang/AST/ASTContext.h" | 
| Faisal Vali | fad9e13 | 2013-09-26 19:54:12 +0000 | [diff] [blame] | 17 | #include "clang/AST/ASTLambda.h" | 
| Sebastian Redl | 58a2cd8 | 2011-04-24 16:28:06 +0000 | [diff] [blame] | 18 | #include "clang/AST/ASTMutationListener.h" | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 19 | #include "clang/AST/CXXInheritance.h" | 
| Chandler Carruth | 55fc873 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 20 | #include "clang/AST/CharUnits.h" | 
| Anders Carlsson | 8211eff | 2009-03-24 01:19:16 +0000 | [diff] [blame] | 21 | #include "clang/AST/DeclVisitor.h" | 
| Richard Trieu | de5e75c | 2012-06-14 23:11:34 +0000 | [diff] [blame] | 22 | #include "clang/AST/EvaluatedExprVisitor.h" | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 23 | #include "clang/AST/ExprCXX.h" | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 24 | #include "clang/AST/RecordLayout.h" | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 25 | #include "clang/AST/RecursiveASTVisitor.h" | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 26 | #include "clang/AST/StmtVisitor.h" | 
| Douglas Gregor | 802ab45 | 2009-12-02 22:36:29 +0000 | [diff] [blame] | 27 | #include "clang/AST/TypeLoc.h" | 
| Douglas Gregor | 0218936 | 2008-10-22 21:13:31 +0000 | [diff] [blame] | 28 | #include "clang/AST/TypeOrdering.h" | 
| Anders Carlsson | b790661 | 2009-08-26 23:45:07 +0000 | [diff] [blame] | 29 | #include "clang/Basic/PartialDiagnostic.h" | 
| Aaron Ballman | fff3248 | 2012-12-09 17:45:41 +0000 | [diff] [blame] | 30 | #include "clang/Basic/TargetInfo.h" | 
| Richard Smith | 4ac537b | 2013-07-23 08:14:48 +0000 | [diff] [blame] | 31 | #include "clang/Lex/LiteralSupport.h" | 
| Argyrios Kyrtzidis | 06ad1f5 | 2008-10-06 18:37:09 +0000 | [diff] [blame] | 32 | #include "clang/Lex/Preprocessor.h" | 
| Chandler Carruth | 55fc873 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 33 | #include "clang/Sema/CXXFieldCollector.h" | 
 | 34 | #include "clang/Sema/DeclSpec.h" | 
 | 35 | #include "clang/Sema/Initialization.h" | 
 | 36 | #include "clang/Sema/Lookup.h" | 
 | 37 | #include "clang/Sema/ParsedTemplate.h" | 
 | 38 | #include "clang/Sema/Scope.h" | 
 | 39 | #include "clang/Sema/ScopeInfo.h" | 
| Douglas Gregor | 3fc749d | 2008-12-23 00:26:44 +0000 | [diff] [blame] | 40 | #include "llvm/ADT/STLExtras.h" | 
| Chandler Carruth | 55fc873 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 41 | #include "llvm/ADT/SmallString.h" | 
| Douglas Gregor | f8268ae | 2008-10-22 17:49:05 +0000 | [diff] [blame] | 42 | #include <map> | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 43 | #include <set> | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 44 |  | 
 | 45 | using namespace clang; | 
 | 46 |  | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 47 | //===----------------------------------------------------------------------===// | 
 | 48 | // CheckDefaultArgumentVisitor | 
 | 49 | //===----------------------------------------------------------------------===// | 
 | 50 |  | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 51 | namespace { | 
 | 52 |   /// CheckDefaultArgumentVisitor - C++ [dcl.fct.default] Traverses | 
 | 53 |   /// the default argument of a parameter to determine whether it | 
 | 54 |   /// contains any ill-formed subexpressions. For example, this will | 
 | 55 |   /// diagnose the use of local variables or parameters within the | 
 | 56 |   /// default argument expression. | 
| Benjamin Kramer | 85b4521 | 2009-11-28 19:45:26 +0000 | [diff] [blame] | 57 |   class CheckDefaultArgumentVisitor | 
| Chris Lattner | b77792e | 2008-07-26 22:17:49 +0000 | [diff] [blame] | 58 |     : public StmtVisitor<CheckDefaultArgumentVisitor, bool> { | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 59 |     Expr *DefaultArg; | 
 | 60 |     Sema *S; | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 61 |  | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 62 |   public: | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 63 |     CheckDefaultArgumentVisitor(Expr *defarg, Sema *s) | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 64 |       : DefaultArg(defarg), S(s) {} | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 65 |  | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 66 |     bool VisitExpr(Expr *Node); | 
 | 67 |     bool VisitDeclRefExpr(DeclRefExpr *DRE); | 
| Douglas Gregor | 796da18 | 2008-11-04 14:32:21 +0000 | [diff] [blame] | 68 |     bool VisitCXXThisExpr(CXXThisExpr *ThisE); | 
| Douglas Gregor | f0459f8 | 2012-02-10 23:30:22 +0000 | [diff] [blame] | 69 |     bool VisitLambdaExpr(LambdaExpr *Lambda); | 
| John McCall | 045d252 | 2013-04-09 01:56:28 +0000 | [diff] [blame] | 70 |     bool VisitPseudoObjectExpr(PseudoObjectExpr *POE); | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 71 |   }; | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 72 |  | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 73 |   /// VisitExpr - Visit all of the children of this expression. | 
 | 74 |   bool CheckDefaultArgumentVisitor::VisitExpr(Expr *Node) { | 
 | 75 |     bool IsInvalid = false; | 
| John McCall | 7502c1d | 2011-02-13 04:07:26 +0000 | [diff] [blame] | 76 |     for (Stmt::child_range I = Node->children(); I; ++I) | 
| Chris Lattner | b77792e | 2008-07-26 22:17:49 +0000 | [diff] [blame] | 77 |       IsInvalid |= Visit(*I); | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 78 |     return IsInvalid; | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 79 |   } | 
 | 80 |  | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 81 |   /// VisitDeclRefExpr - Visit a reference to a declaration, to | 
 | 82 |   /// determine whether this declaration can be used in the default | 
 | 83 |   /// argument expression. | 
 | 84 |   bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(DeclRefExpr *DRE) { | 
| Douglas Gregor | 8e9bebd | 2008-10-21 16:13:35 +0000 | [diff] [blame] | 85 |     NamedDecl *Decl = DRE->getDecl(); | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 86 |     if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Decl)) { | 
 | 87 |       // C++ [dcl.fct.default]p9 | 
 | 88 |       //   Default arguments are evaluated each time the function is | 
 | 89 |       //   called. The order of evaluation of function arguments is | 
 | 90 |       //   unspecified. Consequently, parameters of a function shall not | 
 | 91 |       //   be used in default argument expressions, even if they are not | 
 | 92 |       //   evaluated. Parameters of a function declared before a default | 
 | 93 |       //   argument expression are in scope and can hide namespace and | 
 | 94 |       //   class member names. | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 95 |       return S->Diag(DRE->getLocStart(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 96 |                      diag::err_param_default_argument_references_param) | 
| Chris Lattner | 08631c5 | 2008-11-23 21:45:46 +0000 | [diff] [blame] | 97 |          << Param->getDeclName() << DefaultArg->getSourceRange(); | 
| Steve Naroff | 248a753 | 2008-04-15 22:42:06 +0000 | [diff] [blame] | 98 |     } else if (VarDecl *VDecl = dyn_cast<VarDecl>(Decl)) { | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 99 |       // C++ [dcl.fct.default]p7 | 
 | 100 |       //   Local variables shall not be used in default argument | 
 | 101 |       //   expressions. | 
| John McCall | b6bbcc9 | 2010-10-15 04:57:14 +0000 | [diff] [blame] | 102 |       if (VDecl->isLocalVarDecl()) | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 103 |         return S->Diag(DRE->getLocStart(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 104 |                        diag::err_param_default_argument_references_local) | 
| Chris Lattner | 08631c5 | 2008-11-23 21:45:46 +0000 | [diff] [blame] | 105 |           << VDecl->getDeclName() << DefaultArg->getSourceRange(); | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 106 |     } | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 107 |  | 
| Douglas Gregor | 3996f23 | 2008-11-04 13:41:56 +0000 | [diff] [blame] | 108 |     return false; | 
 | 109 |   } | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 110 |  | 
| Douglas Gregor | 796da18 | 2008-11-04 14:32:21 +0000 | [diff] [blame] | 111 |   /// VisitCXXThisExpr - Visit a C++ "this" expression. | 
 | 112 |   bool CheckDefaultArgumentVisitor::VisitCXXThisExpr(CXXThisExpr *ThisE) { | 
 | 113 |     // C++ [dcl.fct.default]p8: | 
 | 114 |     //   The keyword this shall not be used in a default argument of a | 
 | 115 |     //   member function. | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 116 |     return S->Diag(ThisE->getLocStart(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 117 |                    diag::err_param_default_argument_references_this) | 
 | 118 |                << ThisE->getSourceRange(); | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 119 |   } | 
| Douglas Gregor | f0459f8 | 2012-02-10 23:30:22 +0000 | [diff] [blame] | 120 |  | 
| John McCall | 045d252 | 2013-04-09 01:56:28 +0000 | [diff] [blame] | 121 |   bool CheckDefaultArgumentVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *POE) { | 
 | 122 |     bool Invalid = false; | 
 | 123 |     for (PseudoObjectExpr::semantics_iterator | 
 | 124 |            i = POE->semantics_begin(), e = POE->semantics_end(); i != e; ++i) { | 
 | 125 |       Expr *E = *i; | 
 | 126 |  | 
 | 127 |       // Look through bindings. | 
 | 128 |       if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) { | 
 | 129 |         E = OVE->getSourceExpr(); | 
 | 130 |         assert(E && "pseudo-object binding without source expression?"); | 
 | 131 |       } | 
 | 132 |  | 
 | 133 |       Invalid |= Visit(E); | 
 | 134 |     } | 
 | 135 |     return Invalid; | 
 | 136 |   } | 
 | 137 |  | 
| Douglas Gregor | f0459f8 | 2012-02-10 23:30:22 +0000 | [diff] [blame] | 138 |   bool CheckDefaultArgumentVisitor::VisitLambdaExpr(LambdaExpr *Lambda) { | 
 | 139 |     // C++11 [expr.lambda.prim]p13: | 
 | 140 |     //   A lambda-expression appearing in a default argument shall not | 
 | 141 |     //   implicitly or explicitly capture any entity. | 
 | 142 |     if (Lambda->capture_begin() == Lambda->capture_end()) | 
 | 143 |       return false; | 
 | 144 |  | 
 | 145 |     return S->Diag(Lambda->getLocStart(),  | 
 | 146 |                    diag::err_lambda_capture_default_arg); | 
 | 147 |   } | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 148 | } | 
 | 149 |  | 
| Richard Smith | 0b0ca47 | 2013-04-10 06:11:48 +0000 | [diff] [blame] | 150 | void | 
 | 151 | Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc, | 
 | 152 |                                                  const CXXMethodDecl *Method) { | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 153 |   // If we have an MSAny spec already, don't bother. | 
 | 154 |   if (!Method || ComputedEST == EST_MSAny) | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 155 |     return; | 
 | 156 |  | 
 | 157 |   const FunctionProtoType *Proto | 
 | 158 |     = Method->getType()->getAs<FunctionProtoType>(); | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 159 |   Proto = Self->ResolveExceptionSpec(CallLoc, Proto); | 
 | 160 |   if (!Proto) | 
 | 161 |     return; | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 162 |  | 
 | 163 |   ExceptionSpecificationType EST = Proto->getExceptionSpecType(); | 
 | 164 |  | 
 | 165 |   // If this function can throw any exceptions, make a note of that. | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 166 |   if (EST == EST_MSAny || EST == EST_None) { | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 167 |     ClearExceptions(); | 
 | 168 |     ComputedEST = EST; | 
 | 169 |     return; | 
 | 170 |   } | 
 | 171 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 172 |   // FIXME: If the call to this decl is using any of its default arguments, we | 
 | 173 |   // need to search them for potentially-throwing calls. | 
 | 174 |  | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 175 |   // If this function has a basic noexcept, it doesn't affect the outcome. | 
 | 176 |   if (EST == EST_BasicNoexcept) | 
 | 177 |     return; | 
 | 178 |  | 
 | 179 |   // If we have a throw-all spec at this point, ignore the function. | 
 | 180 |   if (ComputedEST == EST_None) | 
 | 181 |     return; | 
 | 182 |  | 
 | 183 |   // If we're still at noexcept(true) and there's a nothrow() callee, | 
 | 184 |   // change to that specification. | 
 | 185 |   if (EST == EST_DynamicNone) { | 
 | 186 |     if (ComputedEST == EST_BasicNoexcept) | 
 | 187 |       ComputedEST = EST_DynamicNone; | 
 | 188 |     return; | 
 | 189 |   } | 
 | 190 |  | 
 | 191 |   // Check out noexcept specs. | 
 | 192 |   if (EST == EST_ComputedNoexcept) { | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 193 |     FunctionProtoType::NoexceptResult NR = | 
 | 194 |         Proto->getNoexceptSpec(Self->Context); | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 195 |     assert(NR != FunctionProtoType::NR_NoNoexcept && | 
 | 196 |            "Must have noexcept result for EST_ComputedNoexcept."); | 
 | 197 |     assert(NR != FunctionProtoType::NR_Dependent && | 
 | 198 |            "Should not generate implicit declarations for dependent cases, " | 
 | 199 |            "and don't know how to handle them anyway."); | 
 | 200 |  | 
 | 201 |     // noexcept(false) -> no spec on the new function | 
 | 202 |     if (NR == FunctionProtoType::NR_Throw) { | 
 | 203 |       ClearExceptions(); | 
 | 204 |       ComputedEST = EST_None; | 
 | 205 |     } | 
 | 206 |     // noexcept(true) won't change anything either. | 
 | 207 |     return; | 
 | 208 |   } | 
 | 209 |  | 
 | 210 |   assert(EST == EST_Dynamic && "EST case not considered earlier."); | 
 | 211 |   assert(ComputedEST != EST_None && | 
 | 212 |          "Shouldn't collect exceptions when throw-all is guaranteed."); | 
 | 213 |   ComputedEST = EST_Dynamic; | 
 | 214 |   // Record the exceptions in this function's exception specification. | 
 | 215 |   for (FunctionProtoType::exception_iterator E = Proto->exception_begin(), | 
 | 216 |                                           EEnd = Proto->exception_end(); | 
 | 217 |        E != EEnd; ++E) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 218 |     if (ExceptionsSeen.insert(Self->Context.getCanonicalType(*E))) | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 219 |       Exceptions.push_back(*E); | 
 | 220 | } | 
 | 221 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 222 | void Sema::ImplicitExceptionSpecification::CalledExpr(Expr *E) { | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 223 |   if (!E || ComputedEST == EST_MSAny) | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 224 |     return; | 
 | 225 |  | 
 | 226 |   // FIXME: | 
 | 227 |   // | 
 | 228 |   // C++0x [except.spec]p14: | 
| NAKAMURA Takumi | 4857947 | 2011-06-21 03:19:28 +0000 | [diff] [blame] | 229 |   //   [An] implicit exception-specification specifies the type-id T if and | 
 | 230 |   // only if T is allowed by the exception-specification of a function directly | 
 | 231 |   // invoked by f's implicit definition; f shall allow all exceptions if any | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 232 |   // function it directly invokes allows all exceptions, and f shall allow no | 
 | 233 |   // exceptions if every function it directly invokes allows no exceptions. | 
 | 234 |   // | 
 | 235 |   // Note in particular that if an implicit exception-specification is generated | 
 | 236 |   // for a function containing a throw-expression, that specification can still | 
 | 237 |   // be noexcept(true). | 
 | 238 |   // | 
 | 239 |   // Note also that 'directly invoked' is not defined in the standard, and there | 
 | 240 |   // is no indication that we should only consider potentially-evaluated calls. | 
 | 241 |   // | 
 | 242 |   // Ultimately we should implement the intent of the standard: the exception | 
 | 243 |   // specification should be the set of exceptions which can be thrown by the | 
 | 244 |   // implicit definition. For now, we assume that any non-nothrow expression can | 
 | 245 |   // throw any exception. | 
 | 246 |  | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 247 |   if (Self->canThrow(E)) | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 248 |     ComputedEST = EST_None; | 
 | 249 | } | 
 | 250 |  | 
| Anders Carlsson | ed961f9 | 2009-08-25 02:29:20 +0000 | [diff] [blame] | 251 | bool | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 252 | Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 253 |                               SourceLocation EqualLoc) { | 
| Anders Carlsson | 5653ca5 | 2009-08-25 13:46:13 +0000 | [diff] [blame] | 254 |   if (RequireCompleteType(Param->getLocation(), Param->getType(), | 
 | 255 |                           diag::err_typecheck_decl_incomplete_type)) { | 
 | 256 |     Param->setInvalidDecl(); | 
 | 257 |     return true; | 
 | 258 |   } | 
 | 259 |  | 
| Anders Carlsson | ed961f9 | 2009-08-25 02:29:20 +0000 | [diff] [blame] | 260 |   // C++ [dcl.fct.default]p5 | 
 | 261 |   //   A default argument expression is implicitly converted (clause | 
 | 262 |   //   4) to the parameter type. The default argument expression has | 
 | 263 |   //   the same semantic constraints as the initializer expression in | 
 | 264 |   //   a declaration of a variable of the parameter type, using the | 
 | 265 |   //   copy-initialization semantics (8.5). | 
| Fariborz Jahanian | 745da3a | 2010-09-24 17:30:16 +0000 | [diff] [blame] | 266 |   InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, | 
 | 267 |                                                                     Param); | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 268 |   InitializationKind Kind = InitializationKind::CreateCopy(Param->getLocation(), | 
 | 269 |                                                            EqualLoc); | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 270 |   InitializationSequence InitSeq(*this, Entity, Kind, Arg); | 
| Benjamin Kramer | 5354e77 | 2012-08-23 23:38:35 +0000 | [diff] [blame] | 271 |   ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Arg); | 
| Eli Friedman | 4a2c19b | 2009-12-22 02:46:13 +0000 | [diff] [blame] | 272 |   if (Result.isInvalid()) | 
| Anders Carlsson | 9351c17 | 2009-08-25 03:18:48 +0000 | [diff] [blame] | 273 |     return true; | 
| Eli Friedman | 4a2c19b | 2009-12-22 02:46:13 +0000 | [diff] [blame] | 274 |   Arg = Result.takeAs<Expr>(); | 
| Anders Carlsson | ed961f9 | 2009-08-25 02:29:20 +0000 | [diff] [blame] | 275 |  | 
| Richard Smith | 6c3af3d | 2013-01-17 01:17:56 +0000 | [diff] [blame] | 276 |   CheckCompletedExpr(Arg, EqualLoc); | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 277 |   Arg = MaybeCreateExprWithCleanups(Arg); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 278 |  | 
| Anders Carlsson | ed961f9 | 2009-08-25 02:29:20 +0000 | [diff] [blame] | 279 |   // Okay: add the default argument to the parameter | 
 | 280 |   Param->setDefaultArg(Arg); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 281 |  | 
| Douglas Gregor | 8cfb7a3 | 2010-10-12 18:23:32 +0000 | [diff] [blame] | 282 |   // We have already instantiated this parameter; provide each of the  | 
 | 283 |   // instantiations with the uninstantiated default argument. | 
 | 284 |   UnparsedDefaultArgInstantiationsMap::iterator InstPos | 
 | 285 |     = UnparsedDefaultArgInstantiations.find(Param); | 
 | 286 |   if (InstPos != UnparsedDefaultArgInstantiations.end()) { | 
 | 287 |     for (unsigned I = 0, N = InstPos->second.size(); I != N; ++I) | 
 | 288 |       InstPos->second[I]->setUninstantiatedDefaultArg(Arg); | 
 | 289 |      | 
 | 290 |     // We're done tracking this parameter's instantiations. | 
 | 291 |     UnparsedDefaultArgInstantiations.erase(InstPos); | 
 | 292 |   } | 
 | 293 |    | 
| Anders Carlsson | 9351c17 | 2009-08-25 03:18:48 +0000 | [diff] [blame] | 294 |   return false; | 
| Anders Carlsson | ed961f9 | 2009-08-25 02:29:20 +0000 | [diff] [blame] | 295 | } | 
 | 296 |  | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 297 | /// ActOnParamDefaultArgument - Check whether the default argument | 
 | 298 | /// provided for a function parameter is well-formed. If so, attach it | 
 | 299 | /// to the parameter declaration. | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 300 | void | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 301 | Sema::ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 302 |                                 Expr *DefaultArg) { | 
 | 303 |   if (!param || !DefaultArg) | 
| Douglas Gregor | 4c4f7cb | 2009-06-22 23:20:33 +0000 | [diff] [blame] | 304 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 305 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 306 |   ParmVarDecl *Param = cast<ParmVarDecl>(param); | 
| Anders Carlsson | 5e300d1 | 2009-06-12 16:51:40 +0000 | [diff] [blame] | 307 |   UnparsedDefaultArgLocs.erase(Param); | 
 | 308 |  | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 309 |   // Default arguments are only permitted in C++ | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 310 |   if (!getLangOpts().CPlusPlus) { | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 311 |     Diag(EqualLoc, diag::err_param_default_argument) | 
 | 312 |       << DefaultArg->getSourceRange(); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 313 |     Param->setInvalidDecl(); | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 314 |     return; | 
 | 315 |   } | 
 | 316 |  | 
| Douglas Gregor | 6f52675 | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 317 |   // Check for unexpanded parameter packs. | 
 | 318 |   if (DiagnoseUnexpandedParameterPack(DefaultArg, UPPC_DefaultArgument)) { | 
 | 319 |     Param->setInvalidDecl(); | 
 | 320 |     return; | 
 | 321 |   }     | 
 | 322 |        | 
| Anders Carlsson | 66e3067 | 2009-08-25 01:02:06 +0000 | [diff] [blame] | 323 |   // Check that the default argument is well-formed | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 324 |   CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg, this); | 
 | 325 |   if (DefaultArgChecker.Visit(DefaultArg)) { | 
| Anders Carlsson | 66e3067 | 2009-08-25 01:02:06 +0000 | [diff] [blame] | 326 |     Param->setInvalidDecl(); | 
 | 327 |     return; | 
 | 328 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 329 |  | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 330 |   SetParamDefaultArgument(Param, DefaultArg, EqualLoc); | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 331 | } | 
 | 332 |  | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 333 | /// ActOnParamUnparsedDefaultArgument - We've seen a default | 
 | 334 | /// argument for a function parameter, but we can't parse it yet | 
 | 335 | /// because we're inside a class definition. Note that this default | 
 | 336 | /// argument will be parsed later. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 337 | void Sema::ActOnParamUnparsedDefaultArgument(Decl *param, | 
| Anders Carlsson | 5e300d1 | 2009-06-12 16:51:40 +0000 | [diff] [blame] | 338 |                                              SourceLocation EqualLoc, | 
 | 339 |                                              SourceLocation ArgLoc) { | 
| Douglas Gregor | 4c4f7cb | 2009-06-22 23:20:33 +0000 | [diff] [blame] | 340 |   if (!param) | 
 | 341 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 342 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 343 |   ParmVarDecl *Param = cast<ParmVarDecl>(param); | 
| Nick Lewycky | ee0bc3b | 2013-09-22 10:06:57 +0000 | [diff] [blame] | 344 |   Param->setUnparsedDefaultArg(); | 
| Anders Carlsson | 5e300d1 | 2009-06-12 16:51:40 +0000 | [diff] [blame] | 345 |   UnparsedDefaultArgLocs[Param] = ArgLoc; | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 346 | } | 
 | 347 |  | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 348 | /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of | 
 | 349 | /// the default argument for the parameter param failed. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 350 | void Sema::ActOnParamDefaultArgumentError(Decl *param) { | 
| Douglas Gregor | 4c4f7cb | 2009-06-22 23:20:33 +0000 | [diff] [blame] | 351 |   if (!param) | 
 | 352 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 353 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 354 |   ParmVarDecl *Param = cast<ParmVarDecl>(param); | 
| Anders Carlsson | 5e300d1 | 2009-06-12 16:51:40 +0000 | [diff] [blame] | 355 |   Param->setInvalidDecl(); | 
| Anders Carlsson | 5e300d1 | 2009-06-12 16:51:40 +0000 | [diff] [blame] | 356 |   UnparsedDefaultArgLocs.erase(Param); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 357 | } | 
 | 358 |  | 
| Douglas Gregor | 6d6eb57 | 2008-05-07 04:49:29 +0000 | [diff] [blame] | 359 | /// CheckExtraCXXDefaultArguments - Check for any extra default | 
 | 360 | /// arguments in the declarator, which is not a function declaration | 
 | 361 | /// or definition and therefore is not permitted to have default | 
 | 362 | /// arguments. This routine should be invoked for every declarator | 
 | 363 | /// that is not a function declaration or definition. | 
 | 364 | void Sema::CheckExtraCXXDefaultArguments(Declarator &D) { | 
 | 365 |   // C++ [dcl.fct.default]p3 | 
 | 366 |   //   A default argument expression shall be specified only in the | 
 | 367 |   //   parameter-declaration-clause of a function declaration or in a | 
 | 368 |   //   template-parameter (14.1). It shall not be specified for a | 
 | 369 |   //   parameter pack. If it is specified in a | 
 | 370 |   //   parameter-declaration-clause, it shall not occur within a | 
 | 371 |   //   declarator or abstract-declarator of a parameter-declaration. | 
| Richard Smith | 3cdbbdc | 2013-03-06 01:37:38 +0000 | [diff] [blame] | 372 |   bool MightBeFunction = D.isFunctionDeclarationContext(); | 
| Chris Lattner | b28317a | 2009-03-28 19:18:32 +0000 | [diff] [blame] | 373 |   for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { | 
| Douglas Gregor | 6d6eb57 | 2008-05-07 04:49:29 +0000 | [diff] [blame] | 374 |     DeclaratorChunk &chunk = D.getTypeObject(i); | 
 | 375 |     if (chunk.Kind == DeclaratorChunk::Function) { | 
| Richard Smith | 3cdbbdc | 2013-03-06 01:37:38 +0000 | [diff] [blame] | 376 |       if (MightBeFunction) { | 
 | 377 |         // This is a function declaration. It can have default arguments, but | 
 | 378 |         // keep looking in case its return type is a function type with default | 
 | 379 |         // arguments. | 
 | 380 |         MightBeFunction = false; | 
 | 381 |         continue; | 
 | 382 |       } | 
| Chris Lattner | b28317a | 2009-03-28 19:18:32 +0000 | [diff] [blame] | 383 |       for (unsigned argIdx = 0, e = chunk.Fun.NumArgs; argIdx != e; ++argIdx) { | 
 | 384 |         ParmVarDecl *Param = | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 385 |           cast<ParmVarDecl>(chunk.Fun.ArgInfo[argIdx].Param); | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 386 |         if (Param->hasUnparsedDefaultArg()) { | 
 | 387 |           CachedTokens *Toks = chunk.Fun.ArgInfo[argIdx].DefaultArgTokens; | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 388 |           Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc) | 
| Richard Smith | 3cdbbdc | 2013-03-06 01:37:38 +0000 | [diff] [blame] | 389 |             << SourceRange((*Toks)[1].getLocation(), | 
 | 390 |                            Toks->back().getLocation()); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 391 |           delete Toks; | 
 | 392 |           chunk.Fun.ArgInfo[argIdx].DefaultArgTokens = 0; | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 393 |         } else if (Param->getDefaultArg()) { | 
 | 394 |           Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc) | 
 | 395 |             << Param->getDefaultArg()->getSourceRange(); | 
 | 396 |           Param->setDefaultArg(0); | 
| Douglas Gregor | 6d6eb57 | 2008-05-07 04:49:29 +0000 | [diff] [blame] | 397 |         } | 
 | 398 |       } | 
| Richard Smith | 3cdbbdc | 2013-03-06 01:37:38 +0000 | [diff] [blame] | 399 |     } else if (chunk.Kind != DeclaratorChunk::Paren) { | 
 | 400 |       MightBeFunction = false; | 
| Douglas Gregor | 6d6eb57 | 2008-05-07 04:49:29 +0000 | [diff] [blame] | 401 |     } | 
 | 402 |   } | 
 | 403 | } | 
 | 404 |  | 
| David Majnemer | f6a144f | 2013-06-25 23:09:30 +0000 | [diff] [blame] | 405 | static bool functionDeclHasDefaultArgument(const FunctionDecl *FD) { | 
 | 406 |   for (unsigned NumParams = FD->getNumParams(); NumParams > 0; --NumParams) { | 
 | 407 |     const ParmVarDecl *PVD = FD->getParamDecl(NumParams-1); | 
 | 408 |     if (!PVD->hasDefaultArg()) | 
 | 409 |       return false; | 
 | 410 |     if (!PVD->hasInheritedDefaultArg()) | 
 | 411 |       return true; | 
 | 412 |   } | 
 | 413 |   return false; | 
 | 414 | } | 
 | 415 |  | 
| Craig Topper | 1a6eac8 | 2012-09-21 04:33:26 +0000 | [diff] [blame] | 416 | /// MergeCXXFunctionDecl - Merge two declarations of the same C++ | 
 | 417 | /// function, once we already know that they have the same | 
 | 418 | /// type. Subroutine of MergeFunctionDecl. Returns true if there was an | 
 | 419 | /// error, false otherwise. | 
| James Molloy | 9cda03f | 2012-03-13 08:55:35 +0000 | [diff] [blame] | 420 | bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, | 
 | 421 |                                 Scope *S) { | 
| Douglas Gregor | cda9c67 | 2009-02-16 17:45:42 +0000 | [diff] [blame] | 422 |   bool Invalid = false; | 
 | 423 |  | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 424 |   // C++ [dcl.fct.default]p4: | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 425 |   //   For non-template functions, default arguments can be added in | 
 | 426 |   //   later declarations of a function in the same | 
 | 427 |   //   scope. Declarations in different scopes have completely | 
 | 428 |   //   distinct sets of default arguments. That is, declarations in | 
 | 429 |   //   inner scopes do not acquire default arguments from | 
 | 430 |   //   declarations in outer scopes, and vice versa. In a given | 
 | 431 |   //   function declaration, all parameters subsequent to a | 
 | 432 |   //   parameter with a default argument shall have default | 
 | 433 |   //   arguments supplied in this or previous declarations. A | 
 | 434 |   //   default argument shall not be redefined by a later | 
 | 435 |   //   declaration (not even to the same value). | 
| Douglas Gregor | 6cc1518 | 2009-09-11 18:44:32 +0000 | [diff] [blame] | 436 |   // | 
 | 437 |   // C++ [dcl.fct.default]p6: | 
| Richard Smith | a41c97a | 2013-09-20 01:15:31 +0000 | [diff] [blame] | 438 |   //   Except for member functions of class templates, the default arguments | 
 | 439 |   //   in a member function definition that appears outside of the class | 
 | 440 |   //   definition are added to the set of default arguments provided by the | 
| Douglas Gregor | 6cc1518 | 2009-09-11 18:44:32 +0000 | [diff] [blame] | 441 |   //   member function declaration in the class definition. | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 442 |   for (unsigned p = 0, NumParams = Old->getNumParams(); p < NumParams; ++p) { | 
 | 443 |     ParmVarDecl *OldParam = Old->getParamDecl(p); | 
 | 444 |     ParmVarDecl *NewParam = New->getParamDecl(p); | 
 | 445 |  | 
| James Molloy | 9cda03f | 2012-03-13 08:55:35 +0000 | [diff] [blame] | 446 |     bool OldParamHasDfl = OldParam->hasDefaultArg(); | 
 | 447 |     bool NewParamHasDfl = NewParam->hasDefaultArg(); | 
 | 448 |  | 
 | 449 |     NamedDecl *ND = Old; | 
| Richard Smith | a41c97a | 2013-09-20 01:15:31 +0000 | [diff] [blame] | 450 |  | 
 | 451 |     // The declaration context corresponding to the scope is the semantic | 
 | 452 |     // parent, unless this is a local function declaration, in which case | 
 | 453 |     // it is that surrounding function. | 
 | 454 |     DeclContext *ScopeDC = New->getLexicalDeclContext(); | 
 | 455 |     if (!ScopeDC->isFunctionOrMethod()) | 
 | 456 |       ScopeDC = New->getDeclContext(); | 
 | 457 |     if (S && !isDeclInScope(ND, ScopeDC, S) && | 
 | 458 |         !New->getDeclContext()->isRecord()) | 
| James Molloy | 9cda03f | 2012-03-13 08:55:35 +0000 | [diff] [blame] | 459 |       // Ignore default parameters of old decl if they are not in | 
| Richard Smith | a41c97a | 2013-09-20 01:15:31 +0000 | [diff] [blame] | 460 |       // the same scope and this is not an out-of-line definition of | 
 | 461 |       // a member function. | 
| James Molloy | 9cda03f | 2012-03-13 08:55:35 +0000 | [diff] [blame] | 462 |       OldParamHasDfl = false; | 
 | 463 |  | 
 | 464 |     if (OldParamHasDfl && NewParamHasDfl) { | 
| Francois Pichet | 8cf9049 | 2011-04-10 04:58:30 +0000 | [diff] [blame] | 465 |  | 
| Francois Pichet | 8d051e0 | 2011-04-10 03:03:52 +0000 | [diff] [blame] | 466 |       unsigned DiagDefaultParamID = | 
 | 467 |         diag::err_param_default_argument_redefinition; | 
 | 468 |  | 
 | 469 |       // MSVC accepts that default parameters be redefined for member functions | 
 | 470 |       // of template class. The new default parameter's value is ignored. | 
 | 471 |       Invalid = true; | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 472 |       if (getLangOpts().MicrosoftExt) { | 
| Francois Pichet | 8d051e0 | 2011-04-10 03:03:52 +0000 | [diff] [blame] | 473 |         CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(New); | 
 | 474 |         if (MD && MD->getParent()->getDescribedClassTemplate()) { | 
| Francois Pichet | 8cf9049 | 2011-04-10 04:58:30 +0000 | [diff] [blame] | 475 |           // Merge the old default argument into the new parameter. | 
 | 476 |           NewParam->setHasInheritedDefaultArg(); | 
 | 477 |           if (OldParam->hasUninstantiatedDefaultArg()) | 
 | 478 |             NewParam->setUninstantiatedDefaultArg( | 
 | 479 |                                       OldParam->getUninstantiatedDefaultArg()); | 
 | 480 |           else | 
 | 481 |             NewParam->setDefaultArg(OldParam->getInit()); | 
| Francois Pichet | cf320c6 | 2011-04-22 08:25:24 +0000 | [diff] [blame] | 482 |           DiagDefaultParamID = diag::warn_param_default_argument_redefinition; | 
| Francois Pichet | 8d051e0 | 2011-04-10 03:03:52 +0000 | [diff] [blame] | 483 |           Invalid = false; | 
 | 484 |         } | 
 | 485 |       } | 
| Douglas Gregor | 4f123ff | 2010-01-13 00:12:48 +0000 | [diff] [blame] | 486 |        | 
| Francois Pichet | 8cf9049 | 2011-04-10 04:58:30 +0000 | [diff] [blame] | 487 |       // FIXME: If we knew where the '=' was, we could easily provide a fix-it  | 
 | 488 |       // hint here. Alternatively, we could walk the type-source information | 
 | 489 |       // for NewParam to find the last source location in the type... but it | 
 | 490 |       // isn't worth the effort right now. This is the kind of test case that | 
 | 491 |       // is hard to get right: | 
| Douglas Gregor | 4f123ff | 2010-01-13 00:12:48 +0000 | [diff] [blame] | 492 |       //   int f(int); | 
 | 493 |       //   void g(int (*fp)(int) = f); | 
 | 494 |       //   void g(int (*fp)(int) = &f); | 
| Francois Pichet | 8d051e0 | 2011-04-10 03:03:52 +0000 | [diff] [blame] | 495 |       Diag(NewParam->getLocation(), DiagDefaultParamID) | 
| Douglas Gregor | 4f123ff | 2010-01-13 00:12:48 +0000 | [diff] [blame] | 496 |         << NewParam->getDefaultArgRange(); | 
| Douglas Gregor | 6cc1518 | 2009-09-11 18:44:32 +0000 | [diff] [blame] | 497 |        | 
 | 498 |       // Look for the function declaration where the default argument was | 
 | 499 |       // actually written, which may be a declaration prior to Old. | 
| Douglas Gregor | ef96ee0 | 2012-01-14 16:38:05 +0000 | [diff] [blame] | 500 |       for (FunctionDecl *Older = Old->getPreviousDecl(); | 
 | 501 |            Older; Older = Older->getPreviousDecl()) { | 
| Douglas Gregor | 6cc1518 | 2009-09-11 18:44:32 +0000 | [diff] [blame] | 502 |         if (!Older->getParamDecl(p)->hasDefaultArg()) | 
 | 503 |           break; | 
 | 504 |          | 
 | 505 |         OldParam = Older->getParamDecl(p); | 
 | 506 |       }         | 
 | 507 |        | 
 | 508 |       Diag(OldParam->getLocation(), diag::note_previous_definition) | 
 | 509 |         << OldParam->getDefaultArgRange(); | 
| James Molloy | 9cda03f | 2012-03-13 08:55:35 +0000 | [diff] [blame] | 510 |     } else if (OldParamHasDfl) { | 
| John McCall | 3d6c178 | 2010-05-04 01:53:42 +0000 | [diff] [blame] | 511 |       // Merge the old default argument into the new parameter. | 
 | 512 |       // It's important to use getInit() here;  getDefaultArg() | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 513 |       // strips off any top-level ExprWithCleanups. | 
| John McCall | bf73b35 | 2010-03-12 18:31:32 +0000 | [diff] [blame] | 514 |       NewParam->setHasInheritedDefaultArg(); | 
| Douglas Gregor | d85cef5 | 2009-09-17 19:51:30 +0000 | [diff] [blame] | 515 |       if (OldParam->hasUninstantiatedDefaultArg()) | 
 | 516 |         NewParam->setUninstantiatedDefaultArg( | 
 | 517 |                                       OldParam->getUninstantiatedDefaultArg()); | 
 | 518 |       else | 
| John McCall | 3d6c178 | 2010-05-04 01:53:42 +0000 | [diff] [blame] | 519 |         NewParam->setDefaultArg(OldParam->getInit()); | 
| James Molloy | 9cda03f | 2012-03-13 08:55:35 +0000 | [diff] [blame] | 520 |     } else if (NewParamHasDfl) { | 
| Douglas Gregor | 6cc1518 | 2009-09-11 18:44:32 +0000 | [diff] [blame] | 521 |       if (New->getDescribedFunctionTemplate()) { | 
 | 522 |         // Paragraph 4, quoted above, only applies to non-template functions. | 
 | 523 |         Diag(NewParam->getLocation(), | 
 | 524 |              diag::err_param_default_argument_template_redecl) | 
 | 525 |           << NewParam->getDefaultArgRange(); | 
 | 526 |         Diag(Old->getLocation(), diag::note_template_prev_declaration) | 
 | 527 |           << false; | 
| Douglas Gregor | 096ebfd | 2009-10-13 17:02:54 +0000 | [diff] [blame] | 528 |       } else if (New->getTemplateSpecializationKind() | 
 | 529 |                    != TSK_ImplicitInstantiation && | 
 | 530 |                  New->getTemplateSpecializationKind() != TSK_Undeclared) { | 
 | 531 |         // C++ [temp.expr.spec]p21: | 
 | 532 |         //   Default function arguments shall not be specified in a declaration | 
 | 533 |         //   or a definition for one of the following explicit specializations: | 
 | 534 |         //     - the explicit specialization of a function template; | 
| Douglas Gregor | 8c638ab | 2009-10-13 23:52:38 +0000 | [diff] [blame] | 535 |         //     - the explicit specialization of a member function template; | 
 | 536 |         //     - the explicit specialization of a member function of a class  | 
| Douglas Gregor | 096ebfd | 2009-10-13 17:02:54 +0000 | [diff] [blame] | 537 |         //       template where the class template specialization to which the | 
 | 538 |         //       member function specialization belongs is implicitly  | 
 | 539 |         //       instantiated. | 
 | 540 |         Diag(NewParam->getLocation(), diag::err_template_spec_default_arg) | 
 | 541 |           << (New->getTemplateSpecializationKind() ==TSK_ExplicitSpecialization) | 
 | 542 |           << New->getDeclName() | 
 | 543 |           << NewParam->getDefaultArgRange(); | 
| Douglas Gregor | 6cc1518 | 2009-09-11 18:44:32 +0000 | [diff] [blame] | 544 |       } else if (New->getDeclContext()->isDependentContext()) { | 
 | 545 |         // C++ [dcl.fct.default]p6 (DR217): | 
 | 546 |         //   Default arguments for a member function of a class template shall  | 
 | 547 |         //   be specified on the initial declaration of the member function  | 
 | 548 |         //   within the class template. | 
 | 549 |         // | 
 | 550 |         // Reading the tea leaves a bit in DR217 and its reference to DR205  | 
 | 551 |         // leads me to the conclusion that one cannot add default function  | 
 | 552 |         // arguments for an out-of-line definition of a member function of a  | 
 | 553 |         // dependent type. | 
 | 554 |         int WhichKind = 2; | 
 | 555 |         if (CXXRecordDecl *Record  | 
 | 556 |               = dyn_cast<CXXRecordDecl>(New->getDeclContext())) { | 
 | 557 |           if (Record->getDescribedClassTemplate()) | 
 | 558 |             WhichKind = 0; | 
 | 559 |           else if (isa<ClassTemplatePartialSpecializationDecl>(Record)) | 
 | 560 |             WhichKind = 1; | 
 | 561 |           else | 
 | 562 |             WhichKind = 2; | 
 | 563 |         } | 
 | 564 |          | 
 | 565 |         Diag(NewParam->getLocation(),  | 
 | 566 |              diag::err_param_default_argument_member_template_redecl) | 
 | 567 |           << WhichKind | 
 | 568 |           << NewParam->getDefaultArgRange(); | 
 | 569 |       } | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 570 |     } | 
 | 571 |   } | 
 | 572 |  | 
| Richard Smith | b8abff6 | 2012-11-28 03:45:24 +0000 | [diff] [blame] | 573 |   // DR1344: If a default argument is added outside a class definition and that | 
 | 574 |   // default argument makes the function a special member function, the program | 
 | 575 |   // is ill-formed. This can only happen for constructors. | 
 | 576 |   if (isa<CXXConstructorDecl>(New) && | 
 | 577 |       New->getMinRequiredArguments() < Old->getMinRequiredArguments()) { | 
 | 578 |     CXXSpecialMember NewSM = getSpecialMember(cast<CXXMethodDecl>(New)), | 
 | 579 |                      OldSM = getSpecialMember(cast<CXXMethodDecl>(Old)); | 
 | 580 |     if (NewSM != OldSM) { | 
 | 581 |       ParmVarDecl *NewParam = New->getParamDecl(New->getMinRequiredArguments()); | 
 | 582 |       assert(NewParam->hasDefaultArg()); | 
 | 583 |       Diag(NewParam->getLocation(), diag::err_default_arg_makes_ctor_special) | 
 | 584 |         << NewParam->getDefaultArgRange() << NewSM; | 
 | 585 |       Diag(Old->getLocation(), diag::note_previous_declaration); | 
 | 586 |     } | 
 | 587 |   } | 
 | 588 |  | 
| Richard Smith | ff23488 | 2012-02-20 23:28:05 +0000 | [diff] [blame] | 589 |   // C++11 [dcl.constexpr]p1: If any declaration of a function or function | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 590 |   // template has a constexpr specifier then all its declarations shall | 
| Richard Smith | ff23488 | 2012-02-20 23:28:05 +0000 | [diff] [blame] | 591 |   // contain the constexpr specifier. | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 592 |   if (New->isConstexpr() != Old->isConstexpr()) { | 
 | 593 |     Diag(New->getLocation(), diag::err_constexpr_redecl_mismatch) | 
 | 594 |       << New << New->isConstexpr(); | 
 | 595 |     Diag(Old->getLocation(), diag::note_previous_declaration); | 
 | 596 |     Invalid = true; | 
 | 597 |   } | 
 | 598 |  | 
| David Majnemer | f6a144f | 2013-06-25 23:09:30 +0000 | [diff] [blame] | 599 |   // C++11 [dcl.fct.default]p4: If a friend declaration specifies a default | 
| NAKAMURA Takumi | fd527a4 | 2013-07-17 17:57:52 +0000 | [diff] [blame] | 600 |   // argument expression, that declaration shall be a definition and shall be | 
| David Majnemer | f6a144f | 2013-06-25 23:09:30 +0000 | [diff] [blame] | 601 |   // the only declaration of the function or function template in the | 
 | 602 |   // translation unit. | 
 | 603 |   if (Old->getFriendObjectKind() == Decl::FOK_Undeclared && | 
 | 604 |       functionDeclHasDefaultArgument(Old)) { | 
 | 605 |     Diag(New->getLocation(), diag::err_friend_decl_with_def_arg_redeclared); | 
 | 606 |     Diag(Old->getLocation(), diag::note_previous_declaration); | 
 | 607 |     Invalid = true; | 
 | 608 |   } | 
 | 609 |  | 
| Douglas Gregor | e13ad83 | 2010-02-12 07:32:17 +0000 | [diff] [blame] | 610 |   if (CheckEquivalentExceptionSpec(Old, New)) | 
| Sebastian Redl | 4994d2d | 2009-07-04 11:39:00 +0000 | [diff] [blame] | 611 |     Invalid = true; | 
| Sebastian Redl | 4994d2d | 2009-07-04 11:39:00 +0000 | [diff] [blame] | 612 |  | 
| Douglas Gregor | cda9c67 | 2009-02-16 17:45:42 +0000 | [diff] [blame] | 613 |   return Invalid; | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 614 | } | 
 | 615 |  | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 616 | /// \brief Merge the exception specifications of two variable declarations. | 
 | 617 | /// | 
 | 618 | /// This is called when there's a redeclaration of a VarDecl. The function | 
 | 619 | /// checks if the redeclaration might have an exception specification and | 
 | 620 | /// validates compatibility and merges the specs if necessary. | 
 | 621 | void Sema::MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old) { | 
 | 622 |   // Shortcut if exceptions are disabled. | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 623 |   if (!getLangOpts().CXXExceptions) | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 624 |     return; | 
 | 625 |  | 
 | 626 |   assert(Context.hasSameType(New->getType(), Old->getType()) && | 
 | 627 |          "Should only be called if types are otherwise the same."); | 
 | 628 |  | 
 | 629 |   QualType NewType = New->getType(); | 
 | 630 |   QualType OldType = Old->getType(); | 
 | 631 |  | 
 | 632 |   // We're only interested in pointers and references to functions, as well | 
 | 633 |   // as pointers to member functions. | 
 | 634 |   if (const ReferenceType *R = NewType->getAs<ReferenceType>()) { | 
 | 635 |     NewType = R->getPointeeType(); | 
 | 636 |     OldType = OldType->getAs<ReferenceType>()->getPointeeType(); | 
 | 637 |   } else if (const PointerType *P = NewType->getAs<PointerType>()) { | 
 | 638 |     NewType = P->getPointeeType(); | 
 | 639 |     OldType = OldType->getAs<PointerType>()->getPointeeType(); | 
 | 640 |   } else if (const MemberPointerType *M = NewType->getAs<MemberPointerType>()) { | 
 | 641 |     NewType = M->getPointeeType(); | 
 | 642 |     OldType = OldType->getAs<MemberPointerType>()->getPointeeType(); | 
 | 643 |   } | 
 | 644 |  | 
 | 645 |   if (!NewType->isFunctionProtoType()) | 
 | 646 |     return; | 
 | 647 |  | 
 | 648 |   // There's lots of special cases for functions. For function pointers, system | 
 | 649 |   // libraries are hopefully not as broken so that we don't need these | 
 | 650 |   // workarounds. | 
 | 651 |   if (CheckEquivalentExceptionSpec( | 
 | 652 |         OldType->getAs<FunctionProtoType>(), Old->getLocation(), | 
 | 653 |         NewType->getAs<FunctionProtoType>(), New->getLocation())) { | 
 | 654 |     New->setInvalidDecl(); | 
 | 655 |   } | 
 | 656 | } | 
 | 657 |  | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 658 | /// CheckCXXDefaultArguments - Verify that the default arguments for a | 
 | 659 | /// function declaration are well-formed according to C++ | 
 | 660 | /// [dcl.fct.default]. | 
 | 661 | void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) { | 
 | 662 |   unsigned NumParams = FD->getNumParams(); | 
 | 663 |   unsigned p; | 
 | 664 |  | 
 | 665 |   // Find first parameter with a default argument | 
 | 666 |   for (p = 0; p < NumParams; ++p) { | 
 | 667 |     ParmVarDecl *Param = FD->getParamDecl(p); | 
| Richard Smith | 7974c60 | 2013-04-17 16:25:20 +0000 | [diff] [blame] | 668 |     if (Param->hasDefaultArg()) | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 669 |       break; | 
 | 670 |   } | 
 | 671 |  | 
 | 672 |   // C++ [dcl.fct.default]p4: | 
 | 673 |   //   In a given function declaration, all parameters | 
 | 674 |   //   subsequent to a parameter with a default argument shall | 
 | 675 |   //   have default arguments supplied in this or previous | 
 | 676 |   //   declarations. A default argument shall not be redefined | 
 | 677 |   //   by a later declaration (not even to the same value). | 
 | 678 |   unsigned LastMissingDefaultArg = 0; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 679 |   for (; p < NumParams; ++p) { | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 680 |     ParmVarDecl *Param = FD->getParamDecl(p); | 
| Anders Carlsson | 5f49a0c | 2009-08-25 01:23:32 +0000 | [diff] [blame] | 681 |     if (!Param->hasDefaultArg()) { | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 682 |       if (Param->isInvalidDecl()) | 
 | 683 |         /* We already complained about this parameter. */; | 
 | 684 |       else if (Param->getIdentifier()) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 685 |         Diag(Param->getLocation(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 686 |              diag::err_param_default_argument_missing_name) | 
| Chris Lattner | 43b628c | 2008-11-19 07:32:16 +0000 | [diff] [blame] | 687 |           << Param->getIdentifier(); | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 688 |       else | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 689 |         Diag(Param->getLocation(), | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 690 |              diag::err_param_default_argument_missing); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 691 |  | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 692 |       LastMissingDefaultArg = p; | 
 | 693 |     } | 
 | 694 |   } | 
 | 695 |  | 
 | 696 |   if (LastMissingDefaultArg > 0) { | 
 | 697 |     // Some default arguments were missing. Clear out all of the | 
 | 698 |     // default arguments up to (and including) the last missing | 
 | 699 |     // default argument, so that we leave the function parameters | 
 | 700 |     // in a semantically valid state. | 
 | 701 |     for (p = 0; p <= LastMissingDefaultArg; ++p) { | 
 | 702 |       ParmVarDecl *Param = FD->getParamDecl(p); | 
| Anders Carlsson | 5e300d1 | 2009-06-12 16:51:40 +0000 | [diff] [blame] | 703 |       if (Param->hasDefaultArg()) { | 
| Chris Lattner | 3d1cee3 | 2008-04-08 05:04:30 +0000 | [diff] [blame] | 704 |         Param->setDefaultArg(0); | 
 | 705 |       } | 
 | 706 |     } | 
 | 707 |   } | 
 | 708 | } | 
| Douglas Gregor | e37ac4f | 2008-04-13 21:30:24 +0000 | [diff] [blame] | 709 |  | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 710 | // CheckConstexprParameterTypes - Check whether a function's parameter types | 
 | 711 | // are all literal types. If so, return true. If not, produce a suitable | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 712 | // diagnostic and return false. | 
 | 713 | static bool CheckConstexprParameterTypes(Sema &SemaRef, | 
 | 714 |                                          const FunctionDecl *FD) { | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 715 |   unsigned ArgIndex = 0; | 
 | 716 |   const FunctionProtoType *FT = FD->getType()->getAs<FunctionProtoType>(); | 
 | 717 |   for (FunctionProtoType::arg_type_iterator i = FT->arg_type_begin(), | 
 | 718 |        e = FT->arg_type_end(); i != e; ++i, ++ArgIndex) { | 
 | 719 |     const ParmVarDecl *PD = FD->getParamDecl(ArgIndex); | 
 | 720 |     SourceLocation ParamLoc = PD->getLocation(); | 
 | 721 |     if (!(*i)->isDependentType() && | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 722 |         SemaRef.RequireLiteralType(ParamLoc, *i, | 
| Douglas Gregor | f502d8e | 2012-05-04 16:48:41 +0000 | [diff] [blame] | 723 |                                    diag::err_constexpr_non_literal_param, | 
 | 724 |                                    ArgIndex+1, PD->getSourceRange(), | 
 | 725 |                                    isa<CXXConstructorDecl>(FD))) | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 726 |       return false; | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 727 |   } | 
| Joao Matos | 17d35c3 | 2012-08-31 22:18:20 +0000 | [diff] [blame] | 728 |   return true; | 
 | 729 | } | 
 | 730 |  | 
 | 731 | /// \brief Get diagnostic %select index for tag kind for | 
 | 732 | /// record diagnostic message. | 
 | 733 | /// WARNING: Indexes apply to particular diagnostics only! | 
 | 734 | /// | 
 | 735 | /// \returns diagnostic %select index. | 
| Joao Matos | f143ae9 | 2012-09-01 00:13:24 +0000 | [diff] [blame] | 736 | static unsigned getRecordDiagFromTagKind(TagTypeKind Tag) { | 
| Joao Matos | 17d35c3 | 2012-08-31 22:18:20 +0000 | [diff] [blame] | 737 |   switch (Tag) { | 
| Joao Matos | f143ae9 | 2012-09-01 00:13:24 +0000 | [diff] [blame] | 738 |   case TTK_Struct: return 0; | 
 | 739 |   case TTK_Interface: return 1; | 
 | 740 |   case TTK_Class:  return 2; | 
 | 741 |   default: llvm_unreachable("Invalid tag kind for record diagnostic!"); | 
| Joao Matos | 17d35c3 | 2012-08-31 22:18:20 +0000 | [diff] [blame] | 742 |   } | 
| Joao Matos | 17d35c3 | 2012-08-31 22:18:20 +0000 | [diff] [blame] | 743 | } | 
 | 744 |  | 
 | 745 | // CheckConstexprFunctionDecl - Check whether a function declaration satisfies | 
 | 746 | // the requirements of a constexpr function definition or a constexpr | 
 | 747 | // constructor definition. If so, return true. If not, produce appropriate | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 748 | // diagnostics and return false. | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 749 | // | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 750 | // This implements C++11 [dcl.constexpr]p3,4, as amended by DR1360. | 
 | 751 | bool Sema::CheckConstexprFunctionDecl(const FunctionDecl *NewFD) { | 
| Richard Smith | 3534050 | 2012-01-13 04:54:00 +0000 | [diff] [blame] | 752 |   const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); | 
 | 753 |   if (MD && MD->isInstance()) { | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 754 |     // C++11 [dcl.constexpr]p4: | 
 | 755 |     //  The definition of a constexpr constructor shall satisfy the following | 
 | 756 |     //  constraints: | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 757 |     //  - the class shall not have any virtual base classes; | 
| Joao Matos | 17d35c3 | 2012-08-31 22:18:20 +0000 | [diff] [blame] | 758 |     const CXXRecordDecl *RD = MD->getParent(); | 
 | 759 |     if (RD->getNumVBases()) { | 
 | 760 |       Diag(NewFD->getLocation(), diag::err_constexpr_virtual_base) | 
 | 761 |         << isa<CXXConstructorDecl>(NewFD) | 
 | 762 |         << getRecordDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases(); | 
 | 763 |       for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), | 
 | 764 |              E = RD->vbases_end(); I != E; ++I) | 
 | 765 |         Diag(I->getLocStart(), | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 766 |              diag::note_constexpr_virtual_base_here) << I->getSourceRange(); | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 767 |       return false; | 
 | 768 |     } | 
| Richard Smith | 3534050 | 2012-01-13 04:54:00 +0000 | [diff] [blame] | 769 |   } | 
 | 770 |  | 
 | 771 |   if (!isa<CXXConstructorDecl>(NewFD)) { | 
 | 772 |     // C++11 [dcl.constexpr]p3: | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 773 |     //  The definition of a constexpr function shall satisfy the following | 
 | 774 |     //  constraints: | 
 | 775 |     // - it shall not be virtual; | 
 | 776 |     const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD); | 
 | 777 |     if (Method && Method->isVirtual()) { | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 778 |       Diag(NewFD->getLocation(), diag::err_constexpr_virtual); | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 779 |  | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 780 |       // If it's not obvious why this function is virtual, find an overridden | 
 | 781 |       // function which uses the 'virtual' keyword. | 
 | 782 |       const CXXMethodDecl *WrittenVirtual = Method; | 
 | 783 |       while (!WrittenVirtual->isVirtualAsWritten()) | 
 | 784 |         WrittenVirtual = *WrittenVirtual->begin_overridden_methods(); | 
 | 785 |       if (WrittenVirtual != Method) | 
 | 786 |         Diag(WrittenVirtual->getLocation(), | 
 | 787 |              diag::note_overridden_virtual_function); | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 788 |       return false; | 
 | 789 |     } | 
 | 790 |  | 
 | 791 |     // - its return type shall be a literal type; | 
 | 792 |     QualType RT = NewFD->getResultType(); | 
 | 793 |     if (!RT->isDependentType() && | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 794 |         RequireLiteralType(NewFD->getLocation(), RT, | 
| Douglas Gregor | f502d8e | 2012-05-04 16:48:41 +0000 | [diff] [blame] | 795 |                            diag::err_constexpr_non_literal_return)) | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 796 |       return false; | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 797 |   } | 
 | 798 |  | 
| Richard Smith | 3534050 | 2012-01-13 04:54:00 +0000 | [diff] [blame] | 799 |   // - each of its parameter types shall be a literal type; | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 800 |   if (!CheckConstexprParameterTypes(*this, NewFD)) | 
| Richard Smith | 3534050 | 2012-01-13 04:54:00 +0000 | [diff] [blame] | 801 |     return false; | 
 | 802 |  | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 803 |   return true; | 
 | 804 | } | 
 | 805 |  | 
 | 806 | /// Check the given declaration statement is legal within a constexpr function | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 807 | /// body. C++11 [dcl.constexpr]p3,p4, and C++1y [dcl.constexpr]p3. | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 808 | /// | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 809 | /// \return true if the body is OK (maybe only as an extension), false if we | 
 | 810 | ///         have diagnosed a problem. | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 811 | static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl, | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 812 |                                    DeclStmt *DS, SourceLocation &Cxx1yLoc) { | 
 | 813 |   // C++11 [dcl.constexpr]p3 and p4: | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 814 |   //  The definition of a constexpr function(p3) or constructor(p4) [...] shall | 
 | 815 |   //  contain only | 
 | 816 |   for (DeclStmt::decl_iterator DclIt = DS->decl_begin(), | 
 | 817 |          DclEnd = DS->decl_end(); DclIt != DclEnd; ++DclIt) { | 
 | 818 |     switch ((*DclIt)->getKind()) { | 
 | 819 |     case Decl::StaticAssert: | 
 | 820 |     case Decl::Using: | 
 | 821 |     case Decl::UsingShadow: | 
 | 822 |     case Decl::UsingDirective: | 
 | 823 |     case Decl::UnresolvedUsingTypename: | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 824 |     case Decl::UnresolvedUsingValue: | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 825 |       //   - static_assert-declarations | 
 | 826 |       //   - using-declarations, | 
 | 827 |       //   - using-directives, | 
 | 828 |       continue; | 
 | 829 |  | 
 | 830 |     case Decl::Typedef: | 
 | 831 |     case Decl::TypeAlias: { | 
 | 832 |       //   - typedef declarations and alias-declarations that do not define | 
 | 833 |       //     classes or enumerations, | 
 | 834 |       TypedefNameDecl *TN = cast<TypedefNameDecl>(*DclIt); | 
 | 835 |       if (TN->getUnderlyingType()->isVariablyModifiedType()) { | 
 | 836 |         // Don't allow variably-modified types in constexpr functions. | 
 | 837 |         TypeLoc TL = TN->getTypeSourceInfo()->getTypeLoc(); | 
 | 838 |         SemaRef.Diag(TL.getBeginLoc(), diag::err_constexpr_vla) | 
 | 839 |           << TL.getSourceRange() << TL.getType() | 
 | 840 |           << isa<CXXConstructorDecl>(Dcl); | 
 | 841 |         return false; | 
 | 842 |       } | 
 | 843 |       continue; | 
 | 844 |     } | 
 | 845 |  | 
 | 846 |     case Decl::Enum: | 
 | 847 |     case Decl::CXXRecord: | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 848 |       // C++1y allows types to be defined, not just declared. | 
 | 849 |       if (cast<TagDecl>(*DclIt)->isThisDeclarationADefinition()) | 
 | 850 |         SemaRef.Diag(DS->getLocStart(), | 
 | 851 |                      SemaRef.getLangOpts().CPlusPlus1y | 
 | 852 |                        ? diag::warn_cxx11_compat_constexpr_type_definition | 
 | 853 |                        : diag::ext_constexpr_type_definition) | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 854 |           << isa<CXXConstructorDecl>(Dcl); | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 855 |       continue; | 
 | 856 |  | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 857 |     case Decl::EnumConstant: | 
 | 858 |     case Decl::IndirectField: | 
 | 859 |     case Decl::ParmVar: | 
 | 860 |       // These can only appear with other declarations which are banned in | 
 | 861 |       // C++11 and permitted in C++1y, so ignore them. | 
 | 862 |       continue; | 
 | 863 |  | 
 | 864 |     case Decl::Var: { | 
 | 865 |       // C++1y [dcl.constexpr]p3 allows anything except: | 
 | 866 |       //   a definition of a variable of non-literal type or of static or | 
 | 867 |       //   thread storage duration or for which no initialization is performed. | 
 | 868 |       VarDecl *VD = cast<VarDecl>(*DclIt); | 
 | 869 |       if (VD->isThisDeclarationADefinition()) { | 
 | 870 |         if (VD->isStaticLocal()) { | 
 | 871 |           SemaRef.Diag(VD->getLocation(), | 
 | 872 |                        diag::err_constexpr_local_var_static) | 
 | 873 |             << isa<CXXConstructorDecl>(Dcl) | 
 | 874 |             << (VD->getTLSKind() == VarDecl::TLS_Dynamic); | 
 | 875 |           return false; | 
 | 876 |         } | 
| Richard Smith | bebf5b1 | 2013-04-26 14:36:30 +0000 | [diff] [blame] | 877 |         if (!VD->getType()->isDependentType() && | 
 | 878 |             SemaRef.RequireLiteralType( | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 879 |               VD->getLocation(), VD->getType(), | 
 | 880 |               diag::err_constexpr_local_var_non_literal_type, | 
 | 881 |               isa<CXXConstructorDecl>(Dcl))) | 
 | 882 |           return false; | 
 | 883 |         if (!VD->hasInit()) { | 
 | 884 |           SemaRef.Diag(VD->getLocation(), | 
 | 885 |                        diag::err_constexpr_local_var_no_init) | 
 | 886 |             << isa<CXXConstructorDecl>(Dcl); | 
 | 887 |           return false; | 
 | 888 |         } | 
 | 889 |       } | 
 | 890 |       SemaRef.Diag(VD->getLocation(), | 
 | 891 |                    SemaRef.getLangOpts().CPlusPlus1y | 
 | 892 |                     ? diag::warn_cxx11_compat_constexpr_local_var | 
 | 893 |                     : diag::ext_constexpr_local_var) | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 894 |         << isa<CXXConstructorDecl>(Dcl); | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 895 |       continue; | 
 | 896 |     } | 
 | 897 |  | 
 | 898 |     case Decl::NamespaceAlias: | 
 | 899 |     case Decl::Function: | 
 | 900 |       // These are disallowed in C++11 and permitted in C++1y. Allow them | 
 | 901 |       // everywhere as an extension. | 
 | 902 |       if (!Cxx1yLoc.isValid()) | 
 | 903 |         Cxx1yLoc = DS->getLocStart(); | 
 | 904 |       continue; | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 905 |  | 
 | 906 |     default: | 
 | 907 |       SemaRef.Diag(DS->getLocStart(), diag::err_constexpr_body_invalid_stmt) | 
 | 908 |         << isa<CXXConstructorDecl>(Dcl); | 
 | 909 |       return false; | 
 | 910 |     } | 
 | 911 |   } | 
 | 912 |  | 
 | 913 |   return true; | 
 | 914 | } | 
 | 915 |  | 
 | 916 | /// Check that the given field is initialized within a constexpr constructor. | 
 | 917 | /// | 
 | 918 | /// \param Dcl The constexpr constructor being checked. | 
 | 919 | /// \param Field The field being checked. This may be a member of an anonymous | 
 | 920 | ///        struct or union nested within the class being checked. | 
 | 921 | /// \param Inits All declarations, including anonymous struct/union members and | 
 | 922 | ///        indirect members, for which any initialization was provided. | 
 | 923 | /// \param Diagnosed Set to true if an error is produced. | 
 | 924 | static void CheckConstexprCtorInitializer(Sema &SemaRef, | 
 | 925 |                                           const FunctionDecl *Dcl, | 
 | 926 |                                           FieldDecl *Field, | 
 | 927 |                                           llvm::SmallSet<Decl*, 16> &Inits, | 
 | 928 |                                           bool &Diagnosed) { | 
| Eli Friedman | 5fb478b | 2013-06-28 21:07:41 +0000 | [diff] [blame] | 929 |   if (Field->isInvalidDecl()) | 
 | 930 |     return; | 
 | 931 |  | 
| Douglas Gregor | d61db33 | 2011-10-10 17:22:13 +0000 | [diff] [blame] | 932 |   if (Field->isUnnamedBitfield()) | 
 | 933 |     return; | 
| Richard Smith | 30ecfad | 2012-02-09 06:40:58 +0000 | [diff] [blame] | 934 |  | 
 | 935 |   if (Field->isAnonymousStructOrUnion() && | 
 | 936 |       Field->getType()->getAsCXXRecordDecl()->isEmpty()) | 
 | 937 |     return; | 
 | 938 |  | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 939 |   if (!Inits.count(Field)) { | 
 | 940 |     if (!Diagnosed) { | 
 | 941 |       SemaRef.Diag(Dcl->getLocation(), diag::err_constexpr_ctor_missing_init); | 
 | 942 |       Diagnosed = true; | 
 | 943 |     } | 
 | 944 |     SemaRef.Diag(Field->getLocation(), diag::note_constexpr_ctor_missing_init); | 
 | 945 |   } else if (Field->isAnonymousStructOrUnion()) { | 
 | 946 |     const RecordDecl *RD = Field->getType()->castAs<RecordType>()->getDecl(); | 
 | 947 |     for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); | 
 | 948 |          I != E; ++I) | 
 | 949 |       // If an anonymous union contains an anonymous struct of which any member | 
 | 950 |       // is initialized, all members must be initialized. | 
| David Blaikie | 581deb3 | 2012-06-06 20:45:41 +0000 | [diff] [blame] | 951 |       if (!RD->isUnion() || Inits.count(*I)) | 
 | 952 |         CheckConstexprCtorInitializer(SemaRef, Dcl, *I, Inits, Diagnosed); | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 953 |   } | 
 | 954 | } | 
 | 955 |  | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 956 | /// Check the provided statement is allowed in a constexpr function | 
 | 957 | /// definition. | 
 | 958 | static bool | 
 | 959 | CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, | 
| Robert Wilhelm | e7205c0 | 2013-08-10 12:33:24 +0000 | [diff] [blame] | 960 |                            SmallVectorImpl<SourceLocation> &ReturnStmts, | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 961 |                            SourceLocation &Cxx1yLoc) { | 
 | 962 |   // - its function-body shall be [...] a compound-statement that contains only | 
 | 963 |   switch (S->getStmtClass()) { | 
 | 964 |   case Stmt::NullStmtClass: | 
 | 965 |     //   - null statements, | 
 | 966 |     return true; | 
 | 967 |  | 
 | 968 |   case Stmt::DeclStmtClass: | 
 | 969 |     //   - static_assert-declarations | 
 | 970 |     //   - using-declarations, | 
 | 971 |     //   - using-directives, | 
 | 972 |     //   - typedef declarations and alias-declarations that do not define | 
 | 973 |     //     classes or enumerations, | 
 | 974 |     if (!CheckConstexprDeclStmt(SemaRef, Dcl, cast<DeclStmt>(S), Cxx1yLoc)) | 
 | 975 |       return false; | 
 | 976 |     return true; | 
 | 977 |  | 
 | 978 |   case Stmt::ReturnStmtClass: | 
 | 979 |     //   - and exactly one return statement; | 
 | 980 |     if (isa<CXXConstructorDecl>(Dcl)) { | 
 | 981 |       // C++1y allows return statements in constexpr constructors. | 
 | 982 |       if (!Cxx1yLoc.isValid()) | 
 | 983 |         Cxx1yLoc = S->getLocStart(); | 
 | 984 |       return true; | 
 | 985 |     } | 
 | 986 |  | 
 | 987 |     ReturnStmts.push_back(S->getLocStart()); | 
 | 988 |     return true; | 
 | 989 |  | 
 | 990 |   case Stmt::CompoundStmtClass: { | 
 | 991 |     // C++1y allows compound-statements. | 
 | 992 |     if (!Cxx1yLoc.isValid()) | 
 | 993 |       Cxx1yLoc = S->getLocStart(); | 
 | 994 |  | 
 | 995 |     CompoundStmt *CompStmt = cast<CompoundStmt>(S); | 
 | 996 |     for (CompoundStmt::body_iterator BodyIt = CompStmt->body_begin(), | 
 | 997 |            BodyEnd = CompStmt->body_end(); BodyIt != BodyEnd; ++BodyIt) { | 
 | 998 |       if (!CheckConstexprFunctionStmt(SemaRef, Dcl, *BodyIt, ReturnStmts, | 
 | 999 |                                       Cxx1yLoc)) | 
 | 1000 |         return false; | 
 | 1001 |     } | 
 | 1002 |     return true; | 
 | 1003 |   } | 
 | 1004 |  | 
 | 1005 |   case Stmt::AttributedStmtClass: | 
 | 1006 |     if (!Cxx1yLoc.isValid()) | 
 | 1007 |       Cxx1yLoc = S->getLocStart(); | 
 | 1008 |     return true; | 
 | 1009 |  | 
 | 1010 |   case Stmt::IfStmtClass: { | 
 | 1011 |     // C++1y allows if-statements. | 
 | 1012 |     if (!Cxx1yLoc.isValid()) | 
 | 1013 |       Cxx1yLoc = S->getLocStart(); | 
 | 1014 |  | 
 | 1015 |     IfStmt *If = cast<IfStmt>(S); | 
 | 1016 |     if (!CheckConstexprFunctionStmt(SemaRef, Dcl, If->getThen(), ReturnStmts, | 
 | 1017 |                                     Cxx1yLoc)) | 
 | 1018 |       return false; | 
 | 1019 |     if (If->getElse() && | 
 | 1020 |         !CheckConstexprFunctionStmt(SemaRef, Dcl, If->getElse(), ReturnStmts, | 
 | 1021 |                                     Cxx1yLoc)) | 
 | 1022 |       return false; | 
 | 1023 |     return true; | 
 | 1024 |   } | 
 | 1025 |  | 
 | 1026 |   case Stmt::WhileStmtClass: | 
 | 1027 |   case Stmt::DoStmtClass: | 
 | 1028 |   case Stmt::ForStmtClass: | 
 | 1029 |   case Stmt::CXXForRangeStmtClass: | 
 | 1030 |   case Stmt::ContinueStmtClass: | 
 | 1031 |     // C++1y allows all of these. We don't allow them as extensions in C++11, | 
 | 1032 |     // because they don't make sense without variable mutation. | 
 | 1033 |     if (!SemaRef.getLangOpts().CPlusPlus1y) | 
 | 1034 |       break; | 
 | 1035 |     if (!Cxx1yLoc.isValid()) | 
 | 1036 |       Cxx1yLoc = S->getLocStart(); | 
 | 1037 |     for (Stmt::child_range Children = S->children(); Children; ++Children) | 
 | 1038 |       if (*Children && | 
 | 1039 |           !CheckConstexprFunctionStmt(SemaRef, Dcl, *Children, ReturnStmts, | 
 | 1040 |                                       Cxx1yLoc)) | 
 | 1041 |         return false; | 
 | 1042 |     return true; | 
 | 1043 |  | 
 | 1044 |   case Stmt::SwitchStmtClass: | 
 | 1045 |   case Stmt::CaseStmtClass: | 
 | 1046 |   case Stmt::DefaultStmtClass: | 
 | 1047 |   case Stmt::BreakStmtClass: | 
 | 1048 |     // C++1y allows switch-statements, and since they don't need variable | 
 | 1049 |     // mutation, we can reasonably allow them in C++11 as an extension. | 
 | 1050 |     if (!Cxx1yLoc.isValid()) | 
 | 1051 |       Cxx1yLoc = S->getLocStart(); | 
 | 1052 |     for (Stmt::child_range Children = S->children(); Children; ++Children) | 
 | 1053 |       if (*Children && | 
 | 1054 |           !CheckConstexprFunctionStmt(SemaRef, Dcl, *Children, ReturnStmts, | 
 | 1055 |                                       Cxx1yLoc)) | 
 | 1056 |         return false; | 
 | 1057 |     return true; | 
 | 1058 |  | 
 | 1059 |   default: | 
 | 1060 |     if (!isa<Expr>(S)) | 
 | 1061 |       break; | 
 | 1062 |  | 
 | 1063 |     // C++1y allows expression-statements. | 
 | 1064 |     if (!Cxx1yLoc.isValid()) | 
 | 1065 |       Cxx1yLoc = S->getLocStart(); | 
 | 1066 |     return true; | 
 | 1067 |   } | 
 | 1068 |  | 
 | 1069 |   SemaRef.Diag(S->getLocStart(), diag::err_constexpr_body_invalid_stmt) | 
 | 1070 |     << isa<CXXConstructorDecl>(Dcl); | 
 | 1071 |   return false; | 
 | 1072 | } | 
 | 1073 |  | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1074 | /// Check the body for the given constexpr function declaration only contains | 
 | 1075 | /// the permitted types of statement. C++11 [dcl.constexpr]p3,p4. | 
 | 1076 | /// | 
 | 1077 | /// \return true if the body is OK, false if we have diagnosed a problem. | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 1078 | bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) { | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1079 |   if (isa<CXXTryStmt>(Body)) { | 
| Richard Smith | 5ba73e1 | 2012-02-04 00:33:54 +0000 | [diff] [blame] | 1080 |     // C++11 [dcl.constexpr]p3: | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1081 |     //  The definition of a constexpr function shall satisfy the following | 
 | 1082 |     //  constraints: [...] | 
 | 1083 |     // - its function-body shall be = delete, = default, or a | 
 | 1084 |     //   compound-statement | 
 | 1085 |     // | 
| Richard Smith | 5ba73e1 | 2012-02-04 00:33:54 +0000 | [diff] [blame] | 1086 |     // C++11 [dcl.constexpr]p4: | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1087 |     //  In the definition of a constexpr constructor, [...] | 
 | 1088 |     // - its function-body shall not be a function-try-block; | 
 | 1089 |     Diag(Body->getLocStart(), diag::err_constexpr_function_try_block) | 
 | 1090 |       << isa<CXXConstructorDecl>(Dcl); | 
 | 1091 |     return false; | 
 | 1092 |   } | 
 | 1093 |  | 
| Dmitri Gribenko | cfa88f8 | 2013-01-12 19:30:44 +0000 | [diff] [blame] | 1094 |   SmallVector<SourceLocation, 4> ReturnStmts; | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 1095 |  | 
 | 1096 |   // - its function-body shall be [...] a compound-statement that contains only | 
 | 1097 |   //   [... list of cases ...] | 
 | 1098 |   CompoundStmt *CompBody = cast<CompoundStmt>(Body); | 
 | 1099 |   SourceLocation Cxx1yLoc; | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1100 |   for (CompoundStmt::body_iterator BodyIt = CompBody->body_begin(), | 
 | 1101 |          BodyEnd = CompBody->body_end(); BodyIt != BodyEnd; ++BodyIt) { | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 1102 |     if (!CheckConstexprFunctionStmt(*this, Dcl, *BodyIt, ReturnStmts, Cxx1yLoc)) | 
 | 1103 |       return false; | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1104 |   } | 
 | 1105 |  | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 1106 |   if (Cxx1yLoc.isValid()) | 
 | 1107 |     Diag(Cxx1yLoc, | 
 | 1108 |          getLangOpts().CPlusPlus1y | 
 | 1109 |            ? diag::warn_cxx11_compat_constexpr_body_invalid_stmt | 
 | 1110 |            : diag::ext_constexpr_body_invalid_stmt) | 
 | 1111 |       << isa<CXXConstructorDecl>(Dcl); | 
 | 1112 |  | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1113 |   if (const CXXConstructorDecl *Constructor | 
 | 1114 |         = dyn_cast<CXXConstructorDecl>(Dcl)) { | 
 | 1115 |     const CXXRecordDecl *RD = Constructor->getParent(); | 
| Richard Smith | 30ecfad | 2012-02-09 06:40:58 +0000 | [diff] [blame] | 1116 |     // DR1359: | 
 | 1117 |     // - every non-variant non-static data member and base class sub-object | 
 | 1118 |     //   shall be initialized; | 
 | 1119 |     // - if the class is a non-empty union, or for each non-empty anonymous | 
 | 1120 |     //   union member of a non-union class, exactly one non-static data member | 
 | 1121 |     //   shall be initialized; | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1122 |     if (RD->isUnion()) { | 
| Richard Smith | 30ecfad | 2012-02-09 06:40:58 +0000 | [diff] [blame] | 1123 |       if (Constructor->getNumCtorInitializers() == 0 && !RD->isEmpty()) { | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1124 |         Diag(Dcl->getLocation(), diag::err_constexpr_union_ctor_no_init); | 
 | 1125 |         return false; | 
 | 1126 |       } | 
| Richard Smith | 6e43375 | 2011-10-10 16:38:04 +0000 | [diff] [blame] | 1127 |     } else if (!Constructor->isDependentContext() && | 
 | 1128 |                !Constructor->isDelegatingConstructor()) { | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1129 |       assert(RD->getNumVBases() == 0 && "constexpr ctor with virtual bases"); | 
 | 1130 |  | 
 | 1131 |       // Skip detailed checking if we have enough initializers, and we would | 
 | 1132 |       // allow at most one initializer per member. | 
 | 1133 |       bool AnyAnonStructUnionMembers = false; | 
 | 1134 |       unsigned Fields = 0; | 
 | 1135 |       for (CXXRecordDecl::field_iterator I = RD->field_begin(), | 
 | 1136 |            E = RD->field_end(); I != E; ++I, ++Fields) { | 
| David Blaikie | 262bc18 | 2012-04-30 02:36:29 +0000 | [diff] [blame] | 1137 |         if (I->isAnonymousStructOrUnion()) { | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1138 |           AnyAnonStructUnionMembers = true; | 
 | 1139 |           break; | 
 | 1140 |         } | 
 | 1141 |       } | 
 | 1142 |       if (AnyAnonStructUnionMembers || | 
 | 1143 |           Constructor->getNumCtorInitializers() != RD->getNumBases() + Fields) { | 
 | 1144 |         // Check initialization of non-static data members. Base classes are | 
 | 1145 |         // always initialized so do not need to be checked. Dependent bases | 
 | 1146 |         // might not have initializers in the member initializer list. | 
 | 1147 |         llvm::SmallSet<Decl*, 16> Inits; | 
 | 1148 |         for (CXXConstructorDecl::init_const_iterator | 
 | 1149 |                I = Constructor->init_begin(), E = Constructor->init_end(); | 
 | 1150 |              I != E; ++I) { | 
 | 1151 |           if (FieldDecl *FD = (*I)->getMember()) | 
 | 1152 |             Inits.insert(FD); | 
 | 1153 |           else if (IndirectFieldDecl *ID = (*I)->getIndirectMember()) | 
 | 1154 |             Inits.insert(ID->chain_begin(), ID->chain_end()); | 
 | 1155 |         } | 
 | 1156 |  | 
 | 1157 |         bool Diagnosed = false; | 
 | 1158 |         for (CXXRecordDecl::field_iterator I = RD->field_begin(), | 
 | 1159 |              E = RD->field_end(); I != E; ++I) | 
| David Blaikie | 581deb3 | 2012-06-06 20:45:41 +0000 | [diff] [blame] | 1160 |           CheckConstexprCtorInitializer(*this, Dcl, *I, Inits, Diagnosed); | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1161 |         if (Diagnosed) | 
 | 1162 |           return false; | 
 | 1163 |       } | 
 | 1164 |     } | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1165 |   } else { | 
 | 1166 |     if (ReturnStmts.empty()) { | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 1167 |       // C++1y doesn't require constexpr functions to contain a 'return' | 
 | 1168 |       // statement. We still do, unless the return type is void, because | 
 | 1169 |       // otherwise if there's no return statement, the function cannot | 
 | 1170 |       // be used in a core constant expression. | 
| Richard Smith | bebf5b1 | 2013-04-26 14:36:30 +0000 | [diff] [blame] | 1171 |       bool OK = getLangOpts().CPlusPlus1y && Dcl->getResultType()->isVoidType(); | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 1172 |       Diag(Dcl->getLocation(), | 
| Richard Smith | bebf5b1 | 2013-04-26 14:36:30 +0000 | [diff] [blame] | 1173 |            OK ? diag::warn_cxx11_compat_constexpr_body_no_return | 
 | 1174 |               : diag::err_constexpr_body_no_return); | 
 | 1175 |       return OK; | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1176 |     } | 
 | 1177 |     if (ReturnStmts.size() > 1) { | 
| Richard Smith | a10b978 | 2013-04-22 15:31:51 +0000 | [diff] [blame] | 1178 |       Diag(ReturnStmts.back(), | 
 | 1179 |            getLangOpts().CPlusPlus1y | 
 | 1180 |              ? diag::warn_cxx11_compat_constexpr_body_multiple_return | 
 | 1181 |              : diag::ext_constexpr_body_multiple_return); | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1182 |       for (unsigned I = 0; I < ReturnStmts.size() - 1; ++I) | 
 | 1183 |         Diag(ReturnStmts[I], diag::note_constexpr_body_previous_return); | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1184 |     } | 
 | 1185 |   } | 
 | 1186 |  | 
| Richard Smith | 5ba73e1 | 2012-02-04 00:33:54 +0000 | [diff] [blame] | 1187 |   // C++11 [dcl.constexpr]p5: | 
 | 1188 |   //   if no function argument values exist such that the function invocation | 
 | 1189 |   //   substitution would produce a constant expression, the program is | 
 | 1190 |   //   ill-formed; no diagnostic required. | 
 | 1191 |   // C++11 [dcl.constexpr]p3: | 
 | 1192 |   //   - every constructor call and implicit conversion used in initializing the | 
 | 1193 |   //     return value shall be one of those allowed in a constant expression. | 
 | 1194 |   // C++11 [dcl.constexpr]p4: | 
 | 1195 |   //   - every constructor involved in initializing non-static data members and | 
 | 1196 |   //     base class sub-objects shall be a constexpr constructor. | 
| Dmitri Gribenko | cfa88f8 | 2013-01-12 19:30:44 +0000 | [diff] [blame] | 1197 |   SmallVector<PartialDiagnosticAt, 8> Diags; | 
| Richard Smith | 86c3ae4 | 2012-02-13 03:54:03 +0000 | [diff] [blame] | 1198 |   if (!Expr::isPotentialConstantExpr(Dcl, Diags)) { | 
| Richard Smith | afee0ff | 2012-12-09 05:55:43 +0000 | [diff] [blame] | 1199 |     Diag(Dcl->getLocation(), diag::ext_constexpr_function_never_constant_expr) | 
| Richard Smith | 745f514 | 2012-01-27 01:14:48 +0000 | [diff] [blame] | 1200 |       << isa<CXXConstructorDecl>(Dcl); | 
 | 1201 |     for (size_t I = 0, N = Diags.size(); I != N; ++I) | 
 | 1202 |       Diag(Diags[I].first, Diags[I].second); | 
| Richard Smith | afee0ff | 2012-12-09 05:55:43 +0000 | [diff] [blame] | 1203 |     // Don't return false here: we allow this for compatibility in | 
 | 1204 |     // system headers. | 
| Richard Smith | 745f514 | 2012-01-27 01:14:48 +0000 | [diff] [blame] | 1205 |   } | 
 | 1206 |  | 
| Richard Smith | 9f569cc | 2011-10-01 02:31:28 +0000 | [diff] [blame] | 1207 |   return true; | 
 | 1208 | } | 
 | 1209 |  | 
| Douglas Gregor | b48fe38 | 2008-10-31 09:07:45 +0000 | [diff] [blame] | 1210 | /// isCurrentClassName - Determine whether the identifier II is the | 
 | 1211 | /// name of the class type currently being defined. In the case of | 
 | 1212 | /// nested classes, this will only return true if II is the name of | 
 | 1213 | /// the innermost class. | 
| Argyrios Kyrtzidis | eb83ecd | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1214 | bool Sema::isCurrentClassName(const IdentifierInfo &II, Scope *, | 
 | 1215 |                               const CXXScopeSpec *SS) { | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1216 |   assert(getLangOpts().CPlusPlus && "No class names in C!"); | 
| Douglas Gregor | b862b8f | 2010-01-11 23:29:10 +0000 | [diff] [blame] | 1217 |  | 
| Argyrios Kyrtzidis | ef6e647 | 2008-11-08 17:17:31 +0000 | [diff] [blame] | 1218 |   CXXRecordDecl *CurDecl; | 
| Douglas Gregor | e4e5b05 | 2009-03-19 00:18:19 +0000 | [diff] [blame] | 1219 |   if (SS && SS->isSet() && !SS->isInvalid()) { | 
| Douglas Gregor | ac373c4 | 2009-08-21 22:16:40 +0000 | [diff] [blame] | 1220 |     DeclContext *DC = computeDeclContext(*SS, true); | 
| Argyrios Kyrtzidis | ef6e647 | 2008-11-08 17:17:31 +0000 | [diff] [blame] | 1221 |     CurDecl = dyn_cast_or_null<CXXRecordDecl>(DC); | 
 | 1222 |   } else | 
 | 1223 |     CurDecl = dyn_cast_or_null<CXXRecordDecl>(CurContext); | 
 | 1224 |  | 
| Douglas Gregor | 6f7a17b | 2010-02-05 06:12:42 +0000 | [diff] [blame] | 1225 |   if (CurDecl && CurDecl->getIdentifier()) | 
| Douglas Gregor | b48fe38 | 2008-10-31 09:07:45 +0000 | [diff] [blame] | 1226 |     return &II == CurDecl->getIdentifier(); | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 1227 |   return false; | 
| Douglas Gregor | b48fe38 | 2008-10-31 09:07:45 +0000 | [diff] [blame] | 1228 | } | 
 | 1229 |  | 
| Douglas Gregor | 229d47a | 2012-11-10 07:24:09 +0000 | [diff] [blame] | 1230 | /// \brief Determine whether the given class is a base class of the given | 
 | 1231 | /// class, including looking at dependent bases. | 
 | 1232 | static bool findCircularInheritance(const CXXRecordDecl *Class, | 
 | 1233 |                                     const CXXRecordDecl *Current) { | 
 | 1234 |   SmallVector<const CXXRecordDecl*, 8> Queue; | 
 | 1235 |  | 
 | 1236 |   Class = Class->getCanonicalDecl(); | 
 | 1237 |   while (true) { | 
 | 1238 |     for (CXXRecordDecl::base_class_const_iterator I = Current->bases_begin(), | 
 | 1239 |                                                   E = Current->bases_end(); | 
 | 1240 |          I != E; ++I) { | 
 | 1241 |       CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); | 
 | 1242 |       if (!Base) | 
 | 1243 |         continue; | 
 | 1244 |  | 
 | 1245 |       Base = Base->getDefinition(); | 
 | 1246 |       if (!Base) | 
 | 1247 |         continue; | 
 | 1248 |  | 
 | 1249 |       if (Base->getCanonicalDecl() == Class) | 
 | 1250 |         return true; | 
 | 1251 |  | 
 | 1252 |       Queue.push_back(Base); | 
 | 1253 |     } | 
 | 1254 |  | 
 | 1255 |     if (Queue.empty()) | 
 | 1256 |       return false; | 
 | 1257 |  | 
| Robert Wilhelm | 344472e | 2013-08-23 16:11:15 +0000 | [diff] [blame] | 1258 |     Current = Queue.pop_back_val(); | 
| Douglas Gregor | 229d47a | 2012-11-10 07:24:09 +0000 | [diff] [blame] | 1259 |   } | 
 | 1260 |  | 
 | 1261 |   return false; | 
| Douglas Gregor | d777e28 | 2012-11-10 01:18:17 +0000 | [diff] [blame] | 1262 | } | 
 | 1263 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1264 | /// \brief Check the validity of a C++ base class specifier. | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1265 | /// | 
 | 1266 | /// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics | 
 | 1267 | /// and returns NULL otherwise. | 
 | 1268 | CXXBaseSpecifier * | 
 | 1269 | Sema::CheckBaseSpecifier(CXXRecordDecl *Class, | 
 | 1270 |                          SourceRange SpecifierRange, | 
 | 1271 |                          bool Virtual, AccessSpecifier Access, | 
| Douglas Gregor | f90b27a | 2011-01-03 22:36:02 +0000 | [diff] [blame] | 1272 |                          TypeSourceInfo *TInfo, | 
 | 1273 |                          SourceLocation EllipsisLoc) { | 
| Nick Lewycky | 5606220 | 2010-07-26 16:56:01 +0000 | [diff] [blame] | 1274 |   QualType BaseType = TInfo->getType(); | 
 | 1275 |  | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1276 |   // C++ [class.union]p1: | 
 | 1277 |   //   A union shall not have base classes. | 
 | 1278 |   if (Class->isUnion()) { | 
 | 1279 |     Diag(Class->getLocation(), diag::err_base_clause_on_union) | 
 | 1280 |       << SpecifierRange; | 
 | 1281 |     return 0; | 
 | 1282 |   } | 
 | 1283 |  | 
| Douglas Gregor | f90b27a | 2011-01-03 22:36:02 +0000 | [diff] [blame] | 1284 |   if (EllipsisLoc.isValid() &&  | 
 | 1285 |       !TInfo->getType()->containsUnexpandedParameterPack()) { | 
 | 1286 |     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | 
 | 1287 |       << TInfo->getTypeLoc().getSourceRange(); | 
 | 1288 |     EllipsisLoc = SourceLocation(); | 
 | 1289 |   } | 
| Douglas Gregor | d777e28 | 2012-11-10 01:18:17 +0000 | [diff] [blame] | 1290 |  | 
 | 1291 |   SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc(); | 
 | 1292 |  | 
 | 1293 |   if (BaseType->isDependentType()) { | 
 | 1294 |     // Make sure that we don't have circular inheritance among our dependent | 
 | 1295 |     // bases. For non-dependent bases, the check for completeness below handles | 
 | 1296 |     // this. | 
 | 1297 |     if (CXXRecordDecl *BaseDecl = BaseType->getAsCXXRecordDecl()) { | 
 | 1298 |       if (BaseDecl->getCanonicalDecl() == Class->getCanonicalDecl() || | 
 | 1299 |           ((BaseDecl = BaseDecl->getDefinition()) && | 
| Douglas Gregor | 229d47a | 2012-11-10 07:24:09 +0000 | [diff] [blame] | 1300 |            findCircularInheritance(Class, BaseDecl))) { | 
| Douglas Gregor | d777e28 | 2012-11-10 01:18:17 +0000 | [diff] [blame] | 1301 |         Diag(BaseLoc, diag::err_circular_inheritance) | 
 | 1302 |           << BaseType << Context.getTypeDeclType(Class); | 
 | 1303 |  | 
 | 1304 |         if (BaseDecl->getCanonicalDecl() != Class->getCanonicalDecl()) | 
 | 1305 |           Diag(BaseDecl->getLocation(), diag::note_previous_decl) | 
 | 1306 |             << BaseType; | 
 | 1307 |              | 
 | 1308 |         return 0; | 
 | 1309 |       } | 
 | 1310 |     } | 
 | 1311 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1312 |     return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, | 
| Nick Lewycky | 5606220 | 2010-07-26 16:56:01 +0000 | [diff] [blame] | 1313 |                                           Class->getTagKind() == TTK_Class, | 
| Douglas Gregor | f90b27a | 2011-01-03 22:36:02 +0000 | [diff] [blame] | 1314 |                                           Access, TInfo, EllipsisLoc); | 
| Douglas Gregor | d777e28 | 2012-11-10 01:18:17 +0000 | [diff] [blame] | 1315 |   } | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1316 |  | 
 | 1317 |   // Base specifiers must be record types. | 
 | 1318 |   if (!BaseType->isRecordType()) { | 
 | 1319 |     Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange; | 
 | 1320 |     return 0; | 
 | 1321 |   } | 
 | 1322 |  | 
 | 1323 |   // C++ [class.union]p1: | 
 | 1324 |   //   A union shall not be used as a base class. | 
 | 1325 |   if (BaseType->isUnionType()) { | 
 | 1326 |     Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange; | 
 | 1327 |     return 0; | 
 | 1328 |   } | 
 | 1329 |  | 
 | 1330 |   // C++ [class.derived]p2: | 
 | 1331 |   //   The class-name in a base-specifier shall not be an incompletely | 
 | 1332 |   //   defined class. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1333 |   if (RequireCompleteType(BaseLoc, BaseType, | 
| Douglas Gregor | d10099e | 2012-05-04 16:32:21 +0000 | [diff] [blame] | 1334 |                           diag::err_incomplete_base_class, SpecifierRange)) { | 
| John McCall | 572fc62 | 2010-08-17 07:23:57 +0000 | [diff] [blame] | 1335 |     Class->setInvalidDecl(); | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1336 |     return 0; | 
| John McCall | 572fc62 | 2010-08-17 07:23:57 +0000 | [diff] [blame] | 1337 |   } | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1338 |  | 
| Eli Friedman | 1d954f6 | 2009-08-15 21:55:26 +0000 | [diff] [blame] | 1339 |   // If the base class is polymorphic or isn't empty, the new one is/isn't, too. | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 1340 |   RecordDecl *BaseDecl = BaseType->getAs<RecordType>()->getDecl(); | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1341 |   assert(BaseDecl && "Record type has no declaration"); | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 1342 |   BaseDecl = BaseDecl->getDefinition(); | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1343 |   assert(BaseDecl && "Base type is not incomplete, but has no definition"); | 
| David Majnemer | 2f68669 | 2013-06-22 06:43:58 +0000 | [diff] [blame] | 1344 |   CXXRecordDecl *CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl); | 
| Eli Friedman | 1d954f6 | 2009-08-15 21:55:26 +0000 | [diff] [blame] | 1345 |   assert(CXXBaseDecl && "Base type is not a C++ type"); | 
| Eli Friedman | d013733 | 2009-12-05 23:03:49 +0000 | [diff] [blame] | 1346 |  | 
| Anders Carlsson | 1d20927 | 2011-03-25 14:55:14 +0000 | [diff] [blame] | 1347 |   // C++ [class]p3: | 
 | 1348 |   //   If a class is marked final and it appears as a base-type-specifier in  | 
 | 1349 |   //   base-clause, the program is ill-formed. | 
| Anders Carlsson | cb88a1f | 2011-01-24 16:26:15 +0000 | [diff] [blame] | 1350 |   if (CXXBaseDecl->hasAttr<FinalAttr>()) { | 
| Anders Carlsson | dfc2f10 | 2011-01-22 17:51:53 +0000 | [diff] [blame] | 1351 |     Diag(BaseLoc, diag::err_class_marked_final_used_as_base)  | 
 | 1352 |       << CXXBaseDecl->getDeclName(); | 
 | 1353 |     Diag(CXXBaseDecl->getLocation(), diag::note_previous_decl) | 
 | 1354 |       << CXXBaseDecl->getDeclName(); | 
 | 1355 |     return 0; | 
 | 1356 |   } | 
 | 1357 |  | 
| John McCall | 572fc62 | 2010-08-17 07:23:57 +0000 | [diff] [blame] | 1358 |   if (BaseDecl->isInvalidDecl()) | 
 | 1359 |     Class->setInvalidDecl(); | 
| Anders Carlsson | 51f9404 | 2009-12-03 17:49:57 +0000 | [diff] [blame] | 1360 |    | 
 | 1361 |   // Create the base specifier. | 
| Anders Carlsson | 51f9404 | 2009-12-03 17:49:57 +0000 | [diff] [blame] | 1362 |   return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, | 
| Nick Lewycky | 5606220 | 2010-07-26 16:56:01 +0000 | [diff] [blame] | 1363 |                                         Class->getTagKind() == TTK_Class, | 
| Douglas Gregor | f90b27a | 2011-01-03 22:36:02 +0000 | [diff] [blame] | 1364 |                                         Access, TInfo, EllipsisLoc); | 
| Anders Carlsson | 51f9404 | 2009-12-03 17:49:57 +0000 | [diff] [blame] | 1365 | } | 
 | 1366 |  | 
| Douglas Gregor | e37ac4f | 2008-04-13 21:30:24 +0000 | [diff] [blame] | 1367 | /// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is | 
 | 1368 | /// one entry in the base class list of a class specifier, for | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1369 | /// example: | 
 | 1370 | ///    class foo : public bar, virtual private baz { | 
| Douglas Gregor | e37ac4f | 2008-04-13 21:30:24 +0000 | [diff] [blame] | 1371 | /// 'public bar' and 'virtual private baz' are each base-specifiers. | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1372 | BaseResult | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 1373 | Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange, | 
| Richard Smith | 0532140 | 2013-02-19 23:47:15 +0000 | [diff] [blame] | 1374 |                          ParsedAttributes &Attributes, | 
| Douglas Gregor | f8268ae | 2008-10-22 17:49:05 +0000 | [diff] [blame] | 1375 |                          bool Virtual, AccessSpecifier Access, | 
| Douglas Gregor | f90b27a | 2011-01-03 22:36:02 +0000 | [diff] [blame] | 1376 |                          ParsedType basetype, SourceLocation BaseLoc, | 
 | 1377 |                          SourceLocation EllipsisLoc) { | 
| Douglas Gregor | 4c4f7cb | 2009-06-22 23:20:33 +0000 | [diff] [blame] | 1378 |   if (!classdecl) | 
 | 1379 |     return true; | 
 | 1380 |  | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1381 |   AdjustDeclIfTemplate(classdecl); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 1382 |   CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(classdecl); | 
| Douglas Gregor | 5fe8c04 | 2010-02-27 00:25:28 +0000 | [diff] [blame] | 1383 |   if (!Class) | 
 | 1384 |     return true; | 
 | 1385 |  | 
| Richard Smith | 0532140 | 2013-02-19 23:47:15 +0000 | [diff] [blame] | 1386 |   // We do not support any C++11 attributes on base-specifiers yet. | 
 | 1387 |   // Diagnose any attributes we see. | 
 | 1388 |   if (!Attributes.empty()) { | 
 | 1389 |     for (AttributeList *Attr = Attributes.getList(); Attr; | 
 | 1390 |          Attr = Attr->getNext()) { | 
 | 1391 |       if (Attr->isInvalid() || | 
 | 1392 |           Attr->getKind() == AttributeList::IgnoredAttribute) | 
 | 1393 |         continue; | 
 | 1394 |       Diag(Attr->getLoc(), | 
 | 1395 |            Attr->getKind() == AttributeList::UnknownAttribute | 
 | 1396 |              ? diag::warn_unknown_attribute_ignored | 
 | 1397 |              : diag::err_base_specifier_attribute) | 
 | 1398 |         << Attr->getName(); | 
 | 1399 |     } | 
 | 1400 |   } | 
 | 1401 |  | 
| Nick Lewycky | 5606220 | 2010-07-26 16:56:01 +0000 | [diff] [blame] | 1402 |   TypeSourceInfo *TInfo = 0; | 
 | 1403 |   GetTypeFromParser(basetype, &TInfo); | 
| Douglas Gregor | d093722 | 2010-12-13 22:49:22 +0000 | [diff] [blame] | 1404 |  | 
| Douglas Gregor | f90b27a | 2011-01-03 22:36:02 +0000 | [diff] [blame] | 1405 |   if (EllipsisLoc.isInvalid() && | 
 | 1406 |       DiagnoseUnexpandedParameterPack(SpecifierRange.getBegin(), TInfo,  | 
| Douglas Gregor | d093722 | 2010-12-13 22:49:22 +0000 | [diff] [blame] | 1407 |                                       UPPC_BaseType)) | 
 | 1408 |     return true; | 
| Douglas Gregor | f90b27a | 2011-01-03 22:36:02 +0000 | [diff] [blame] | 1409 |    | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1410 |   if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange, | 
| Douglas Gregor | f90b27a | 2011-01-03 22:36:02 +0000 | [diff] [blame] | 1411 |                                                       Virtual, Access, TInfo, | 
 | 1412 |                                                       EllipsisLoc)) | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1413 |     return BaseSpec; | 
| Douglas Gregor | 8a50fe0 | 2012-07-02 21:00:41 +0000 | [diff] [blame] | 1414 |   else | 
 | 1415 |     Class->setInvalidDecl(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1416 |  | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1417 |   return true; | 
| Douglas Gregor | f8268ae | 2008-10-22 17:49:05 +0000 | [diff] [blame] | 1418 | } | 
| Douglas Gregor | e37ac4f | 2008-04-13 21:30:24 +0000 | [diff] [blame] | 1419 |  | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1420 | /// \brief Performs the actual work of attaching the given base class | 
 | 1421 | /// specifiers to a C++ class. | 
 | 1422 | bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, | 
 | 1423 |                                 unsigned NumBases) { | 
 | 1424 |  if (NumBases == 0) | 
 | 1425 |     return false; | 
| Douglas Gregor | f8268ae | 2008-10-22 17:49:05 +0000 | [diff] [blame] | 1426 |  | 
 | 1427 |   // Used to keep track of which base types we have already seen, so | 
 | 1428 |   // that we can properly diagnose redundant direct base types. Note | 
| Douglas Gregor | 57c856b | 2008-10-23 18:13:27 +0000 | [diff] [blame] | 1429 |   // that the key is always the unqualified canonical type of the base | 
 | 1430 |   // class. | 
| Douglas Gregor | f8268ae | 2008-10-22 17:49:05 +0000 | [diff] [blame] | 1431 |   std::map<QualType, CXXBaseSpecifier*, QualTypeOrdering> KnownBaseTypes; | 
 | 1432 |  | 
 | 1433 |   // Copy non-redundant base specifiers into permanent storage. | 
| Douglas Gregor | 57c856b | 2008-10-23 18:13:27 +0000 | [diff] [blame] | 1434 |   unsigned NumGoodBases = 0; | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1435 |   bool Invalid = false; | 
| Douglas Gregor | 57c856b | 2008-10-23 18:13:27 +0000 | [diff] [blame] | 1436 |   for (unsigned idx = 0; idx < NumBases; ++idx) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1437 |     QualType NewBaseType | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1438 |       = Context.getCanonicalType(Bases[idx]->getType()); | 
| Douglas Gregor | a4923eb | 2009-11-16 21:35:15 +0000 | [diff] [blame] | 1439 |     NewBaseType = NewBaseType.getLocalUnqualifiedType(); | 
| Benjamin Kramer | 52c1668 | 2012-03-05 17:20:04 +0000 | [diff] [blame] | 1440 |  | 
 | 1441 |     CXXBaseSpecifier *&KnownBase = KnownBaseTypes[NewBaseType]; | 
 | 1442 |     if (KnownBase) { | 
| Douglas Gregor | f8268ae | 2008-10-22 17:49:05 +0000 | [diff] [blame] | 1443 |       // C++ [class.mi]p3: | 
 | 1444 |       //   A class shall not be specified as a direct base class of a | 
 | 1445 |       //   derived class more than once. | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 1446 |       Diag(Bases[idx]->getLocStart(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 1447 |            diag::err_duplicate_base_class) | 
| Benjamin Kramer | 52c1668 | 2012-03-05 17:20:04 +0000 | [diff] [blame] | 1448 |         << KnownBase->getType() | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1449 |         << Bases[idx]->getSourceRange(); | 
| Douglas Gregor | 57c856b | 2008-10-23 18:13:27 +0000 | [diff] [blame] | 1450 |  | 
 | 1451 |       // Delete the duplicate base class specifier; we're going to | 
 | 1452 |       // overwrite its pointer later. | 
| Douglas Gregor | 2aef06d | 2009-07-22 20:55:49 +0000 | [diff] [blame] | 1453 |       Context.Deallocate(Bases[idx]); | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1454 |  | 
 | 1455 |       Invalid = true; | 
| Douglas Gregor | f8268ae | 2008-10-22 17:49:05 +0000 | [diff] [blame] | 1456 |     } else { | 
 | 1457 |       // Okay, add this new base class. | 
| Benjamin Kramer | 52c1668 | 2012-03-05 17:20:04 +0000 | [diff] [blame] | 1458 |       KnownBase = Bases[idx]; | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1459 |       Bases[NumGoodBases++] = Bases[idx]; | 
| John McCall | e402e72 | 2012-09-25 07:32:39 +0000 | [diff] [blame] | 1460 |       if (const RecordType *Record = NewBaseType->getAs<RecordType>()) { | 
 | 1461 |         const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); | 
 | 1462 |         if (Class->isInterface() && | 
 | 1463 |               (!RD->isInterface() || | 
 | 1464 |                KnownBase->getAccessSpecifier() != AS_public)) { | 
 | 1465 |           // The Microsoft extension __interface does not permit bases that | 
 | 1466 |           // are not themselves public interfaces. | 
 | 1467 |           Diag(KnownBase->getLocStart(), diag::err_invalid_base_in_interface) | 
 | 1468 |             << getRecordDiagFromTagKind(RD->getTagKind()) << RD->getName() | 
 | 1469 |             << RD->getSourceRange(); | 
 | 1470 |           Invalid = true; | 
 | 1471 |         } | 
 | 1472 |         if (RD->hasAttr<WeakAttr>()) | 
 | 1473 |           Class->addAttr(::new (Context) WeakAttr(SourceRange(), Context)); | 
 | 1474 |       } | 
| Douglas Gregor | f8268ae | 2008-10-22 17:49:05 +0000 | [diff] [blame] | 1475 |     } | 
 | 1476 |   } | 
 | 1477 |  | 
 | 1478 |   // Attach the remaining base class specifiers to the derived class. | 
| Douglas Gregor | 2d5b703 | 2010-02-11 01:30:34 +0000 | [diff] [blame] | 1479 |   Class->setBases(Bases, NumGoodBases); | 
| Douglas Gregor | 57c856b | 2008-10-23 18:13:27 +0000 | [diff] [blame] | 1480 |  | 
 | 1481 |   // Delete the remaining (good) base class specifiers, since their | 
 | 1482 |   // data has been copied into the CXXRecordDecl. | 
 | 1483 |   for (unsigned idx = 0; idx < NumGoodBases; ++idx) | 
| Douglas Gregor | 2aef06d | 2009-07-22 20:55:49 +0000 | [diff] [blame] | 1484 |     Context.Deallocate(Bases[idx]); | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1485 |  | 
 | 1486 |   return Invalid; | 
 | 1487 | } | 
 | 1488 |  | 
 | 1489 | /// ActOnBaseSpecifiers - Attach the given base specifiers to the | 
 | 1490 | /// class, after checking whether there are any duplicate base | 
 | 1491 | /// classes. | 
| Richard Trieu | 90ab75b | 2011-09-09 03:18:59 +0000 | [diff] [blame] | 1492 | void Sema::ActOnBaseSpecifiers(Decl *ClassDecl, CXXBaseSpecifier **Bases, | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 1493 |                                unsigned NumBases) { | 
 | 1494 |   if (!ClassDecl || !Bases || !NumBases) | 
 | 1495 |     return; | 
 | 1496 |  | 
 | 1497 |   AdjustDeclIfTemplate(ClassDecl); | 
| Robert Wilhelm | 0d317a0 | 2013-07-22 05:04:01 +0000 | [diff] [blame] | 1498 |   AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl), Bases, NumBases); | 
| Douglas Gregor | e37ac4f | 2008-04-13 21:30:24 +0000 | [diff] [blame] | 1499 | } | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 1500 |  | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1501 | /// \brief Determine whether the type \p Derived is a C++ class that is | 
 | 1502 | /// derived from the type \p Base. | 
 | 1503 | bool Sema::IsDerivedFrom(QualType Derived, QualType Base) { | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1504 |   if (!getLangOpts().CPlusPlus) | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1505 |     return false; | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 1506 |    | 
| Douglas Gregor | 0162c1c | 2013-03-26 23:36:30 +0000 | [diff] [blame] | 1507 |   CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl(); | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 1508 |   if (!DerivedRD) | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1509 |     return false; | 
 | 1510 |    | 
| Douglas Gregor | 0162c1c | 2013-03-26 23:36:30 +0000 | [diff] [blame] | 1511 |   CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 1512 |   if (!BaseRD) | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1513 |     return false; | 
| Douglas Gregor | 0162c1c | 2013-03-26 23:36:30 +0000 | [diff] [blame] | 1514 |  | 
 | 1515 |   // If either the base or the derived type is invalid, don't try to | 
 | 1516 |   // check whether one is derived from the other. | 
 | 1517 |   if (BaseRD->isInvalidDecl() || DerivedRD->isInvalidDecl()) | 
 | 1518 |     return false; | 
 | 1519 |  | 
| John McCall | 86ff308 | 2010-02-04 22:26:26 +0000 | [diff] [blame] | 1520 |   // FIXME: instantiate DerivedRD if necessary.  We need a PoI for this. | 
 | 1521 |   return DerivedRD->hasDefinition() && DerivedRD->isDerivedFrom(BaseRD); | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1522 | } | 
 | 1523 |  | 
 | 1524 | /// \brief Determine whether the type \p Derived is a C++ class that is | 
 | 1525 | /// derived from the type \p Base. | 
 | 1526 | bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) { | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1527 |   if (!getLangOpts().CPlusPlus) | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1528 |     return false; | 
 | 1529 |    | 
| Douglas Gregor | 0162c1c | 2013-03-26 23:36:30 +0000 | [diff] [blame] | 1530 |   CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl(); | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 1531 |   if (!DerivedRD) | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1532 |     return false; | 
 | 1533 |    | 
| Douglas Gregor | 0162c1c | 2013-03-26 23:36:30 +0000 | [diff] [blame] | 1534 |   CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 1535 |   if (!BaseRD) | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1536 |     return false; | 
 | 1537 |    | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1538 |   return DerivedRD->isDerivedFrom(BaseRD, Paths); | 
 | 1539 | } | 
 | 1540 |  | 
| Anders Carlsson | 5cf86ba | 2010-04-24 19:06:50 +0000 | [diff] [blame] | 1541 | void Sema::BuildBasePathArray(const CXXBasePaths &Paths,  | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 1542 |                               CXXCastPath &BasePathArray) { | 
| Anders Carlsson | 5cf86ba | 2010-04-24 19:06:50 +0000 | [diff] [blame] | 1543 |   assert(BasePathArray.empty() && "Base path array must be empty!"); | 
 | 1544 |   assert(Paths.isRecordingPaths() && "Must record paths!"); | 
 | 1545 |    | 
 | 1546 |   const CXXBasePath &Path = Paths.front(); | 
 | 1547 |         | 
 | 1548 |   // We first go backward and check if we have a virtual base. | 
 | 1549 |   // FIXME: It would be better if CXXBasePath had the base specifier for | 
 | 1550 |   // the nearest virtual base. | 
 | 1551 |   unsigned Start = 0; | 
 | 1552 |   for (unsigned I = Path.size(); I != 0; --I) { | 
 | 1553 |     if (Path[I - 1].Base->isVirtual()) { | 
 | 1554 |       Start = I - 1; | 
 | 1555 |       break; | 
 | 1556 |     } | 
 | 1557 |   } | 
 | 1558 |  | 
 | 1559 |   // Now add all bases. | 
 | 1560 |   for (unsigned I = Start, E = Path.size(); I != E; ++I) | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 1561 |     BasePathArray.push_back(const_cast<CXXBaseSpecifier*>(Path[I].Base)); | 
| Anders Carlsson | 5cf86ba | 2010-04-24 19:06:50 +0000 | [diff] [blame] | 1562 | } | 
 | 1563 |  | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 1564 | /// \brief Determine whether the given base path includes a virtual | 
 | 1565 | /// base class. | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 1566 | bool Sema::BasePathInvolvesVirtualBase(const CXXCastPath &BasePath) { | 
 | 1567 |   for (CXXCastPath::const_iterator B = BasePath.begin(),  | 
 | 1568 |                                 BEnd = BasePath.end(); | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 1569 |        B != BEnd; ++B) | 
 | 1570 |     if ((*B)->isVirtual()) | 
 | 1571 |       return true; | 
 | 1572 |  | 
 | 1573 |   return false; | 
 | 1574 | } | 
 | 1575 |  | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1576 | /// CheckDerivedToBaseConversion - Check whether the Derived-to-Base | 
 | 1577 | /// conversion (where Derived and Base are class types) is | 
 | 1578 | /// well-formed, meaning that the conversion is unambiguous (and | 
 | 1579 | /// that all of the base classes are accessible). Returns true | 
 | 1580 | /// and emits a diagnostic if the code is ill-formed, returns false | 
 | 1581 | /// otherwise. Loc is the location where this routine should point to | 
 | 1582 | /// if there is an error, and Range is the source range to highlight | 
 | 1583 | /// if there is an error. | 
 | 1584 | bool | 
 | 1585 | Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 1586 |                                    unsigned InaccessibleBaseID, | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1587 |                                    unsigned AmbigiousBaseConvID, | 
 | 1588 |                                    SourceLocation Loc, SourceRange Range, | 
| Anders Carlsson | e25a96c | 2010-04-24 17:11:09 +0000 | [diff] [blame] | 1589 |                                    DeclarationName Name, | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 1590 |                                    CXXCastPath *BasePath) { | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1591 |   // First, determine whether the path from Derived to Base is | 
 | 1592 |   // ambiguous. This is slightly more expensive than checking whether | 
 | 1593 |   // the Derived to Base conversion exists, because here we need to | 
 | 1594 |   // explore multiple paths to determine if there is an ambiguity. | 
 | 1595 |   CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | 
 | 1596 |                      /*DetectVirtual=*/false); | 
 | 1597 |   bool DerivationOkay = IsDerivedFrom(Derived, Base, Paths); | 
 | 1598 |   assert(DerivationOkay && | 
 | 1599 |          "Can only be used with a derived-to-base conversion"); | 
 | 1600 |   (void)DerivationOkay; | 
 | 1601 |    | 
 | 1602 |   if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) { | 
| Anders Carlsson | 5cf86ba | 2010-04-24 19:06:50 +0000 | [diff] [blame] | 1603 |     if (InaccessibleBaseID) { | 
 | 1604 |       // Check that the base class can be accessed. | 
 | 1605 |       switch (CheckBaseClassAccess(Loc, Base, Derived, Paths.front(), | 
 | 1606 |                                    InaccessibleBaseID)) { | 
 | 1607 |         case AR_inaccessible:  | 
 | 1608 |           return true; | 
 | 1609 |         case AR_accessible:  | 
 | 1610 |         case AR_dependent: | 
 | 1611 |         case AR_delayed: | 
 | 1612 |           break; | 
| Anders Carlsson | e25a96c | 2010-04-24 17:11:09 +0000 | [diff] [blame] | 1613 |       } | 
| John McCall | 6b2accb | 2010-02-10 09:31:12 +0000 | [diff] [blame] | 1614 |     } | 
| Anders Carlsson | 5cf86ba | 2010-04-24 19:06:50 +0000 | [diff] [blame] | 1615 |      | 
 | 1616 |     // Build a base path if necessary. | 
 | 1617 |     if (BasePath) | 
 | 1618 |       BuildBasePathArray(Paths, *BasePath); | 
 | 1619 |     return false; | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1620 |   } | 
 | 1621 |    | 
| David Majnemer | 2f68669 | 2013-06-22 06:43:58 +0000 | [diff] [blame] | 1622 |   if (AmbigiousBaseConvID) { | 
 | 1623 |     // We know that the derived-to-base conversion is ambiguous, and | 
 | 1624 |     // we're going to produce a diagnostic. Perform the derived-to-base | 
 | 1625 |     // search just one more time to compute all of the possible paths so | 
 | 1626 |     // that we can print them out. This is more expensive than any of | 
 | 1627 |     // the previous derived-to-base checks we've done, but at this point | 
 | 1628 |     // performance isn't as much of an issue. | 
 | 1629 |     Paths.clear(); | 
 | 1630 |     Paths.setRecordingPaths(true); | 
 | 1631 |     bool StillOkay = IsDerivedFrom(Derived, Base, Paths); | 
 | 1632 |     assert(StillOkay && "Can only be used with a derived-to-base conversion"); | 
 | 1633 |     (void)StillOkay; | 
 | 1634 |  | 
 | 1635 |     // Build up a textual representation of the ambiguous paths, e.g., | 
 | 1636 |     // D -> B -> A, that will be used to illustrate the ambiguous | 
 | 1637 |     // conversions in the diagnostic. We only print one of the paths | 
 | 1638 |     // to each base class subobject. | 
 | 1639 |     std::string PathDisplayStr = getAmbiguousPathsDisplayString(Paths); | 
 | 1640 |  | 
 | 1641 |     Diag(Loc, AmbigiousBaseConvID) | 
 | 1642 |     << Derived << Base << PathDisplayStr << Range << Name; | 
 | 1643 |   } | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1644 |   return true; | 
 | 1645 | } | 
 | 1646 |  | 
 | 1647 | bool | 
 | 1648 | Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, | 
| Sebastian Redl | a82e4ae | 2009-11-14 21:15:49 +0000 | [diff] [blame] | 1649 |                                    SourceLocation Loc, SourceRange Range, | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 1650 |                                    CXXCastPath *BasePath, | 
| Sebastian Redl | a82e4ae | 2009-11-14 21:15:49 +0000 | [diff] [blame] | 1651 |                                    bool IgnoreAccess) { | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1652 |   return CheckDerivedToBaseConversion(Derived, Base, | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 1653 |                                       IgnoreAccess ? 0 | 
 | 1654 |                                        : diag::err_upcast_to_inaccessible_base, | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1655 |                                       diag::err_ambiguous_derived_to_base_conv, | 
| Anders Carlsson | e25a96c | 2010-04-24 17:11:09 +0000 | [diff] [blame] | 1656 |                                       Loc, Range, DeclarationName(),  | 
 | 1657 |                                       BasePath); | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 1658 | } | 
 | 1659 |  | 
 | 1660 |  | 
 | 1661 | /// @brief Builds a string representing ambiguous paths from a | 
 | 1662 | /// specific derived class to different subobjects of the same base | 
 | 1663 | /// class. | 
 | 1664 | /// | 
 | 1665 | /// This function builds a string that can be used in error messages | 
 | 1666 | /// to show the different paths that one can take through the | 
 | 1667 | /// inheritance hierarchy to go from the derived class to different | 
 | 1668 | /// subobjects of a base class. The result looks something like this: | 
 | 1669 | /// @code | 
 | 1670 | /// struct D -> struct B -> struct A | 
 | 1671 | /// struct D -> struct C -> struct A | 
 | 1672 | /// @endcode | 
 | 1673 | std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) { | 
 | 1674 |   std::string PathDisplayStr; | 
 | 1675 |   std::set<unsigned> DisplayedPaths; | 
 | 1676 |   for (CXXBasePaths::paths_iterator Path = Paths.begin(); | 
 | 1677 |        Path != Paths.end(); ++Path) { | 
 | 1678 |     if (DisplayedPaths.insert(Path->back().SubobjectNumber).second) { | 
 | 1679 |       // We haven't displayed a path to this particular base | 
 | 1680 |       // class subobject yet. | 
 | 1681 |       PathDisplayStr += "\n    "; | 
 | 1682 |       PathDisplayStr += Context.getTypeDeclType(Paths.getOrigin()).getAsString(); | 
 | 1683 |       for (CXXBasePath::const_iterator Element = Path->begin(); | 
 | 1684 |            Element != Path->end(); ++Element) | 
 | 1685 |         PathDisplayStr += " -> " + Element->Base->getType().getAsString(); | 
 | 1686 |     } | 
 | 1687 |   } | 
 | 1688 |    | 
 | 1689 |   return PathDisplayStr; | 
 | 1690 | } | 
 | 1691 |  | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1692 | //===----------------------------------------------------------------------===// | 
 | 1693 | // C++ class member Handling | 
 | 1694 | //===----------------------------------------------------------------------===// | 
 | 1695 |  | 
| Abramo Bagnara | 6206d53 | 2010-06-05 05:09:32 +0000 | [diff] [blame] | 1696 | /// ActOnAccessSpecifier - Parsed an access specifier followed by a colon. | 
| Erik Verbruggen | 5f1c822 | 2011-10-13 09:41:32 +0000 | [diff] [blame] | 1697 | bool Sema::ActOnAccessSpecifier(AccessSpecifier Access, | 
 | 1698 |                                 SourceLocation ASLoc, | 
 | 1699 |                                 SourceLocation ColonLoc, | 
 | 1700 |                                 AttributeList *Attrs) { | 
| Abramo Bagnara | 6206d53 | 2010-06-05 05:09:32 +0000 | [diff] [blame] | 1701 |   assert(Access != AS_none && "Invalid kind for syntactic access specifier!"); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 1702 |   AccessSpecDecl *ASDecl = AccessSpecDecl::Create(Context, Access, CurContext, | 
| Abramo Bagnara | 6206d53 | 2010-06-05 05:09:32 +0000 | [diff] [blame] | 1703 |                                                   ASLoc, ColonLoc); | 
 | 1704 |   CurContext->addHiddenDecl(ASDecl); | 
| Erik Verbruggen | 5f1c822 | 2011-10-13 09:41:32 +0000 | [diff] [blame] | 1705 |   return ProcessAccessDeclAttributeList(ASDecl, Attrs); | 
| Abramo Bagnara | 6206d53 | 2010-06-05 05:09:32 +0000 | [diff] [blame] | 1706 | } | 
 | 1707 |  | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 1708 | /// CheckOverrideControl - Check C++11 override control semantics. | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 1709 | void Sema::CheckOverrideControl(NamedDecl *D) { | 
| Richard Smith | cddbc1d | 2012-09-06 18:32:18 +0000 | [diff] [blame] | 1710 |   if (D->isInvalidDecl()) | 
 | 1711 |     return; | 
 | 1712 |  | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 1713 |   // We only care about "override" and "final" declarations. | 
 | 1714 |   if (!D->hasAttr<OverrideAttr>() && !D->hasAttr<FinalAttr>()) | 
 | 1715 |     return; | 
| Anders Carlsson | 9e682d9 | 2011-01-20 05:57:14 +0000 | [diff] [blame] | 1716 |  | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 1717 |   CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D); | 
| Anders Carlsson | 3ffe183 | 2011-01-20 06:33:26 +0000 | [diff] [blame] | 1718 |  | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 1719 |   // We can't check dependent instance methods. | 
 | 1720 |   if (MD && MD->isInstance() && | 
 | 1721 |       (MD->getParent()->hasAnyDependentBases() || | 
 | 1722 |        MD->getType()->isDependentType())) | 
 | 1723 |     return; | 
 | 1724 |  | 
 | 1725 |   if (MD && !MD->isVirtual()) { | 
 | 1726 |     // If we have a non-virtual method, check if if hides a virtual method. | 
 | 1727 |     // (In that case, it's most likely the method has the wrong type.) | 
 | 1728 |     SmallVector<CXXMethodDecl *, 8> OverloadedMethods; | 
 | 1729 |     FindHiddenVirtualMethods(MD, OverloadedMethods); | 
 | 1730 |  | 
 | 1731 |     if (!OverloadedMethods.empty()) { | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 1732 |       if (OverrideAttr *OA = D->getAttr<OverrideAttr>()) { | 
 | 1733 |         Diag(OA->getLocation(), | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 1734 |              diag::override_keyword_hides_virtual_member_function) | 
 | 1735 |           << "override" << (OverloadedMethods.size() > 1); | 
 | 1736 |       } else if (FinalAttr *FA = D->getAttr<FinalAttr>()) { | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 1737 |         Diag(FA->getLocation(), | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 1738 |              diag::override_keyword_hides_virtual_member_function) | 
 | 1739 |             << "final" << (OverloadedMethods.size() > 1); | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 1740 |       } | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 1741 |       NoteHiddenVirtualMethods(MD, OverloadedMethods); | 
 | 1742 |       MD->setInvalidDecl(); | 
 | 1743 |       return; | 
 | 1744 |     } | 
 | 1745 |     // Fall through into the general case diagnostic. | 
 | 1746 |     // FIXME: We might want to attempt typo correction here. | 
 | 1747 |   } | 
 | 1748 |  | 
 | 1749 |   if (!MD || !MD->isVirtual()) { | 
 | 1750 |     if (OverrideAttr *OA = D->getAttr<OverrideAttr>()) { | 
 | 1751 |       Diag(OA->getLocation(), | 
 | 1752 |            diag::override_keyword_only_allowed_on_virtual_member_functions) | 
 | 1753 |         << "override" << FixItHint::CreateRemoval(OA->getLocation()); | 
 | 1754 |       D->dropAttr<OverrideAttr>(); | 
 | 1755 |     } | 
 | 1756 |     if (FinalAttr *FA = D->getAttr<FinalAttr>()) { | 
 | 1757 |       Diag(FA->getLocation(), | 
 | 1758 |            diag::override_keyword_only_allowed_on_virtual_member_functions) | 
 | 1759 |         << "final" << FixItHint::CreateRemoval(FA->getLocation()); | 
 | 1760 |       D->dropAttr<FinalAttr>(); | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 1761 |     } | 
| Anders Carlsson | 9e682d9 | 2011-01-20 05:57:14 +0000 | [diff] [blame] | 1762 |     return; | 
 | 1763 |   } | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 1764 |  | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 1765 |   // C++11 [class.virtual]p5: | 
 | 1766 |   //   If a virtual function is marked with the virt-specifier override and | 
 | 1767 |   //   does not override a member function of a base class, the program is | 
 | 1768 |   //   ill-formed. | 
 | 1769 |   bool HasOverriddenMethods = | 
 | 1770 |     MD->begin_overridden_methods() != MD->end_overridden_methods(); | 
 | 1771 |   if (MD->hasAttr<OverrideAttr>() && !HasOverriddenMethods) | 
 | 1772 |     Diag(MD->getLocation(), diag::err_function_marked_override_not_overriding) | 
 | 1773 |       << MD->getDeclName(); | 
| Anders Carlsson | 9e682d9 | 2011-01-20 05:57:14 +0000 | [diff] [blame] | 1774 | } | 
 | 1775 |  | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 1776 | /// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member | 
| Anders Carlsson | 2e1c730 | 2011-01-20 16:25:36 +0000 | [diff] [blame] | 1777 | /// function overrides a virtual member function marked 'final', according to | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 1778 | /// C++11 [class.virtual]p4. | 
| Anders Carlsson | 2e1c730 | 2011-01-20 16:25:36 +0000 | [diff] [blame] | 1779 | bool Sema::CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New, | 
 | 1780 |                                                   const CXXMethodDecl *Old) { | 
| Anders Carlsson | cb88a1f | 2011-01-24 16:26:15 +0000 | [diff] [blame] | 1781 |   if (!Old->hasAttr<FinalAttr>()) | 
| Anders Carlsson | f89e042 | 2011-01-23 21:07:30 +0000 | [diff] [blame] | 1782 |     return false; | 
 | 1783 |  | 
 | 1784 |   Diag(New->getLocation(), diag::err_final_function_overridden) | 
 | 1785 |     << New->getDeclName(); | 
 | 1786 |   Diag(Old->getLocation(), diag::note_overridden_virtual_function); | 
 | 1787 |   return true; | 
| Anders Carlsson | 2e1c730 | 2011-01-20 16:25:36 +0000 | [diff] [blame] | 1788 | } | 
 | 1789 |  | 
| Daniel Jasper | f8cc02e | 2012-06-06 08:32:04 +0000 | [diff] [blame] | 1790 | static bool InitializationHasSideEffects(const FieldDecl &FD) { | 
| Richard Smith | 0b8220a | 2012-08-07 21:30:42 +0000 | [diff] [blame] | 1791 |   const Type *T = FD.getType()->getBaseElementTypeUnsafe(); | 
 | 1792 |   // FIXME: Destruction of ObjC lifetime types has side-effects. | 
 | 1793 |   if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) | 
 | 1794 |     return !RD->isCompleteDefinition() || | 
 | 1795 |            !RD->hasTrivialDefaultConstructor() || | 
 | 1796 |            !RD->hasTrivialDestructor(); | 
| Daniel Jasper | f8cc02e | 2012-06-06 08:32:04 +0000 | [diff] [blame] | 1797 |   return false; | 
 | 1798 | } | 
 | 1799 |  | 
| John McCall | 76da55d | 2013-04-16 07:28:30 +0000 | [diff] [blame] | 1800 | static AttributeList *getMSPropertyAttr(AttributeList *list) { | 
 | 1801 |   for (AttributeList* it = list; it != 0; it = it->getNext()) | 
 | 1802 |     if (it->isDeclspecPropertyAttribute()) | 
 | 1803 |       return it; | 
 | 1804 |   return 0; | 
 | 1805 | } | 
 | 1806 |  | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1807 | /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member | 
 | 1808 | /// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 1809 | /// bitfield width if there is one, 'InitExpr' specifies the initializer if | 
| Richard Smith | ca52330 | 2012-06-10 03:12:00 +0000 | [diff] [blame] | 1810 | /// one has been parsed, and 'InitStyle' is set if an in-class initializer is | 
 | 1811 | /// present (but parsing it has been deferred). | 
| Rafael Espindola | fc35cbc | 2013-01-08 20:44:06 +0000 | [diff] [blame] | 1812 | NamedDecl * | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1813 | Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, | 
| Douglas Gregor | 37b372b | 2009-08-20 22:52:58 +0000 | [diff] [blame] | 1814 |                                MultiTemplateParamsArg TemplateParameterLists, | 
| Richard Trieu | f81e5a9 | 2011-09-09 02:00:50 +0000 | [diff] [blame] | 1815 |                                Expr *BW, const VirtSpecifiers &VS, | 
| Richard Smith | ca52330 | 2012-06-10 03:12:00 +0000 | [diff] [blame] | 1816 |                                InClassInitStyle InitStyle) { | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1817 |   const DeclSpec &DS = D.getDeclSpec(); | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1818 |   DeclarationNameInfo NameInfo = GetNameForDeclarator(D); | 
 | 1819 |   DeclarationName Name = NameInfo.getName(); | 
 | 1820 |   SourceLocation Loc = NameInfo.getLoc(); | 
| Douglas Gregor | 90ba6d5 | 2010-11-09 03:31:16 +0000 | [diff] [blame] | 1821 |  | 
 | 1822 |   // For anonymous bitfields, the location should point to the type. | 
 | 1823 |   if (Loc.isInvalid()) | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 1824 |     Loc = D.getLocStart(); | 
| Douglas Gregor | 90ba6d5 | 2010-11-09 03:31:16 +0000 | [diff] [blame] | 1825 |  | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1826 |   Expr *BitWidth = static_cast<Expr*>(BW); | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1827 |  | 
| John McCall | 4bde1e1 | 2010-06-04 08:34:12 +0000 | [diff] [blame] | 1828 |   assert(isa<CXXRecordDecl>(CurContext)); | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 1829 |   assert(!DS.isFriendSpecified()); | 
 | 1830 |  | 
| Richard Smith | 1ab0d90 | 2011-06-25 02:28:38 +0000 | [diff] [blame] | 1831 |   bool isFunc = D.isDeclarationOfFunction(); | 
| John McCall | 4bde1e1 | 2010-06-04 08:34:12 +0000 | [diff] [blame] | 1832 |  | 
| John McCall | e402e72 | 2012-09-25 07:32:39 +0000 | [diff] [blame] | 1833 |   if (cast<CXXRecordDecl>(CurContext)->isInterface()) { | 
 | 1834 |     // The Microsoft extension __interface only permits public member functions | 
 | 1835 |     // and prohibits constructors, destructors, operators, non-public member | 
 | 1836 |     // functions, static methods and data members. | 
 | 1837 |     unsigned InvalidDecl; | 
 | 1838 |     bool ShowDeclName = true; | 
 | 1839 |     if (!isFunc) | 
 | 1840 |       InvalidDecl = (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) ? 0 : 1; | 
 | 1841 |     else if (AS != AS_public) | 
 | 1842 |       InvalidDecl = 2; | 
 | 1843 |     else if (DS.getStorageClassSpec() == DeclSpec::SCS_static) | 
 | 1844 |       InvalidDecl = 3; | 
 | 1845 |     else switch (Name.getNameKind()) { | 
 | 1846 |       case DeclarationName::CXXConstructorName: | 
 | 1847 |         InvalidDecl = 4; | 
 | 1848 |         ShowDeclName = false; | 
 | 1849 |         break; | 
 | 1850 |  | 
 | 1851 |       case DeclarationName::CXXDestructorName: | 
 | 1852 |         InvalidDecl = 5; | 
 | 1853 |         ShowDeclName = false; | 
 | 1854 |         break; | 
 | 1855 |  | 
 | 1856 |       case DeclarationName::CXXOperatorName: | 
 | 1857 |       case DeclarationName::CXXConversionFunctionName: | 
 | 1858 |         InvalidDecl = 6; | 
 | 1859 |         break; | 
 | 1860 |  | 
 | 1861 |       default: | 
 | 1862 |         InvalidDecl = 0; | 
 | 1863 |         break; | 
 | 1864 |     } | 
 | 1865 |  | 
 | 1866 |     if (InvalidDecl) { | 
 | 1867 |       if (ShowDeclName) | 
 | 1868 |         Diag(Loc, diag::err_invalid_member_in_interface) | 
 | 1869 |           << (InvalidDecl-1) << Name; | 
 | 1870 |       else | 
 | 1871 |         Diag(Loc, diag::err_invalid_member_in_interface) | 
 | 1872 |           << (InvalidDecl-1) << ""; | 
 | 1873 |       return 0; | 
 | 1874 |     } | 
 | 1875 |   } | 
 | 1876 |  | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1877 |   // C++ 9.2p6: A member shall not be declared to have automatic storage | 
 | 1878 |   // duration (auto, register) or with the extern storage-class-specifier. | 
| Sebastian Redl | 669d5d7 | 2008-11-14 23:42:31 +0000 | [diff] [blame] | 1879 |   // C++ 7.1.1p8: The mutable specifier can be applied only to names of class | 
 | 1880 |   // data members and cannot be applied to names declared const or static, | 
 | 1881 |   // and cannot be applied to reference members. | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1882 |   switch (DS.getStorageClassSpec()) { | 
| Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 1883 |   case DeclSpec::SCS_unspecified: | 
 | 1884 |   case DeclSpec::SCS_typedef: | 
 | 1885 |   case DeclSpec::SCS_static: | 
 | 1886 |     break; | 
 | 1887 |   case DeclSpec::SCS_mutable: | 
 | 1888 |     if (isFunc) { | 
 | 1889 |       Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_function); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1890 |  | 
| Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 1891 |       // FIXME: It would be nicer if the keyword was ignored only for this | 
 | 1892 |       // declarator. Otherwise we could get follow-up errors. | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1893 |       D.getMutableDeclSpec().ClearStorageClassSpecs(); | 
| Richard Smith | ec64244 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 1894 |     } | 
 | 1895 |     break; | 
 | 1896 |   default: | 
 | 1897 |     Diag(DS.getStorageClassSpecLoc(), | 
 | 1898 |          diag::err_storageclass_invalid_for_member); | 
 | 1899 |     D.getMutableDeclSpec().ClearStorageClassSpecs(); | 
 | 1900 |     break; | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1901 |   } | 
 | 1902 |  | 
| Sebastian Redl | 669d5d7 | 2008-11-14 23:42:31 +0000 | [diff] [blame] | 1903 |   bool isInstField = ((DS.getStorageClassSpec() == DeclSpec::SCS_unspecified || | 
 | 1904 |                        DS.getStorageClassSpec() == DeclSpec::SCS_mutable) && | 
| Argyrios Kyrtzidis | de933f0 | 2008-10-08 22:20:31 +0000 | [diff] [blame] | 1905 |                       !isFunc); | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 1906 |  | 
| David Blaikie | 1d87fba | 2013-01-30 01:22:18 +0000 | [diff] [blame] | 1907 |   if (DS.isConstexprSpecified() && isInstField) { | 
 | 1908 |     SemaDiagnosticBuilder B = | 
 | 1909 |         Diag(DS.getConstexprSpecLoc(), diag::err_invalid_constexpr_member); | 
 | 1910 |     SourceLocation ConstexprLoc = DS.getConstexprSpecLoc(); | 
 | 1911 |     if (InitStyle == ICIS_NoInit) { | 
 | 1912 |       B << 0 << 0 << FixItHint::CreateReplacement(ConstexprLoc, "const"); | 
 | 1913 |       D.getMutableDeclSpec().ClearConstexprSpec(); | 
 | 1914 |       const char *PrevSpec; | 
 | 1915 |       unsigned DiagID; | 
 | 1916 |       bool Failed = D.getMutableDeclSpec().SetTypeQual(DeclSpec::TQ_const, ConstexprLoc, | 
 | 1917 |                                          PrevSpec, DiagID, getLangOpts()); | 
| Matt Beaumont-Gay | 3e55e3e | 2013-01-31 00:08:03 +0000 | [diff] [blame] | 1918 |       (void)Failed; | 
| David Blaikie | 1d87fba | 2013-01-30 01:22:18 +0000 | [diff] [blame] | 1919 |       assert(!Failed && "Making a constexpr member const shouldn't fail"); | 
 | 1920 |     } else { | 
 | 1921 |       B << 1; | 
 | 1922 |       const char *PrevSpec; | 
 | 1923 |       unsigned DiagID; | 
| David Blaikie | 1d87fba | 2013-01-30 01:22:18 +0000 | [diff] [blame] | 1924 |       if (D.getMutableDeclSpec().SetStorageClassSpec( | 
 | 1925 |           *this, DeclSpec::SCS_static, ConstexprLoc, PrevSpec, DiagID)) { | 
| Matt Beaumont-Gay | 3e55e3e | 2013-01-31 00:08:03 +0000 | [diff] [blame] | 1926 |         assert(DS.getStorageClassSpec() == DeclSpec::SCS_mutable && | 
| David Blaikie | 1d87fba | 2013-01-30 01:22:18 +0000 | [diff] [blame] | 1927 |                "This is the only DeclSpec that should fail to be applied"); | 
 | 1928 |         B << 1; | 
 | 1929 |       } else { | 
 | 1930 |         B << 0 << FixItHint::CreateInsertion(ConstexprLoc, "static "); | 
 | 1931 |         isInstField = false; | 
 | 1932 |       } | 
 | 1933 |     } | 
 | 1934 |   } | 
 | 1935 |  | 
| Rafael Espindola | fc35cbc | 2013-01-08 20:44:06 +0000 | [diff] [blame] | 1936 |   NamedDecl *Member; | 
| Chris Lattner | 2479366 | 2009-03-05 22:45:59 +0000 | [diff] [blame] | 1937 |   if (isInstField) { | 
| Douglas Gregor | 922fff2 | 2010-10-13 22:19:53 +0000 | [diff] [blame] | 1938 |     CXXScopeSpec &SS = D.getCXXScopeSpec(); | 
| Douglas Gregor | b5a0187 | 2011-10-09 18:55:59 +0000 | [diff] [blame] | 1939 |  | 
 | 1940 |     // Data members must have identifiers for names. | 
| Benjamin Kramer | c1aa40c | 2012-05-19 16:34:46 +0000 | [diff] [blame] | 1941 |     if (!Name.isIdentifier()) { | 
| Douglas Gregor | b5a0187 | 2011-10-09 18:55:59 +0000 | [diff] [blame] | 1942 |       Diag(Loc, diag::err_bad_variable_name) | 
 | 1943 |         << Name; | 
 | 1944 |       return 0; | 
 | 1945 |     } | 
| Douglas Gregor | f250365 | 2011-09-21 14:40:46 +0000 | [diff] [blame] | 1946 |  | 
| Benjamin Kramer | c1aa40c | 2012-05-19 16:34:46 +0000 | [diff] [blame] | 1947 |     IdentifierInfo *II = Name.getAsIdentifierInfo(); | 
 | 1948 |  | 
| Douglas Gregor | f250365 | 2011-09-21 14:40:46 +0000 | [diff] [blame] | 1949 |     // Member field could not be with "template" keyword. | 
 | 1950 |     // So TemplateParameterLists should be empty in this case. | 
 | 1951 |     if (TemplateParameterLists.size()) { | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 1952 |       TemplateParameterList* TemplateParams = TemplateParameterLists[0]; | 
| Douglas Gregor | f250365 | 2011-09-21 14:40:46 +0000 | [diff] [blame] | 1953 |       if (TemplateParams->size()) { | 
 | 1954 |         // There is no such thing as a member field template. | 
 | 1955 |         Diag(D.getIdentifierLoc(), diag::err_template_member) | 
 | 1956 |             << II | 
 | 1957 |             << SourceRange(TemplateParams->getTemplateLoc(), | 
 | 1958 |                 TemplateParams->getRAngleLoc()); | 
 | 1959 |       } else { | 
 | 1960 |         // There is an extraneous 'template<>' for this member. | 
 | 1961 |         Diag(TemplateParams->getTemplateLoc(), | 
 | 1962 |             diag::err_template_member_noparams) | 
 | 1963 |             << II | 
 | 1964 |             << SourceRange(TemplateParams->getTemplateLoc(), | 
 | 1965 |                 TemplateParams->getRAngleLoc()); | 
 | 1966 |       } | 
 | 1967 |       return 0; | 
 | 1968 |     } | 
 | 1969 |  | 
| Douglas Gregor | 922fff2 | 2010-10-13 22:19:53 +0000 | [diff] [blame] | 1970 |     if (SS.isSet() && !SS.isInvalid()) { | 
 | 1971 |       // The user provided a superfluous scope specifier inside a class | 
 | 1972 |       // definition: | 
 | 1973 |       // | 
 | 1974 |       // class X { | 
 | 1975 |       //   int X::member; | 
 | 1976 |       // }; | 
| Douglas Gregor | 6960587 | 2012-03-28 16:01:27 +0000 | [diff] [blame] | 1977 |       if (DeclContext *DC = computeDeclContext(SS, false)) | 
 | 1978 |         diagnoseQualifiedDeclaration(SS, DC, Name, D.getIdentifierLoc()); | 
| Douglas Gregor | 922fff2 | 2010-10-13 22:19:53 +0000 | [diff] [blame] | 1979 |       else | 
 | 1980 |         Diag(D.getIdentifierLoc(), diag::err_member_qualification) | 
 | 1981 |           << Name << SS.getRange(); | 
| Douglas Gregor | 5d8419c | 2011-11-01 22:13:30 +0000 | [diff] [blame] | 1982 |        | 
| Douglas Gregor | 922fff2 | 2010-10-13 22:19:53 +0000 | [diff] [blame] | 1983 |       SS.clear(); | 
 | 1984 |     } | 
| Douglas Gregor | f250365 | 2011-09-21 14:40:46 +0000 | [diff] [blame] | 1985 |  | 
| John McCall | 76da55d | 2013-04-16 07:28:30 +0000 | [diff] [blame] | 1986 |     AttributeList *MSPropertyAttr = | 
 | 1987 |       getMSPropertyAttr(D.getDeclSpec().getAttributes().getList()); | 
| Eli Friedman | b26f012 | 2013-06-28 20:48:34 +0000 | [diff] [blame] | 1988 |     if (MSPropertyAttr) { | 
 | 1989 |       Member = HandleMSProperty(S, cast<CXXRecordDecl>(CurContext), Loc, D, | 
 | 1990 |                                 BitWidth, InitStyle, AS, MSPropertyAttr); | 
 | 1991 |       if (!Member) | 
 | 1992 |         return 0; | 
 | 1993 |       isInstField = false; | 
 | 1994 |     } else { | 
 | 1995 |       Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, | 
 | 1996 |                                 BitWidth, InitStyle, AS); | 
 | 1997 |       assert(Member && "HandleField never returns null"); | 
 | 1998 |     } | 
 | 1999 |   } else { | 
 | 2000 |     assert(InitStyle == ICIS_NoInit || D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static); | 
 | 2001 |  | 
 | 2002 |     Member = HandleDeclarator(S, D, TemplateParameterLists); | 
 | 2003 |     if (!Member) | 
 | 2004 |       return 0; | 
 | 2005 |  | 
 | 2006 |     // Non-instance-fields can't have a bitfield. | 
 | 2007 |     if (BitWidth) { | 
| Chris Lattner | 8b963ef | 2009-03-05 23:01:03 +0000 | [diff] [blame] | 2008 |       if (Member->isInvalidDecl()) { | 
 | 2009 |         // don't emit another diagnostic. | 
| Douglas Gregor | 2d2e9cf | 2009-03-11 20:22:50 +0000 | [diff] [blame] | 2010 |       } else if (isa<VarDecl>(Member)) { | 
| Chris Lattner | 8b963ef | 2009-03-05 23:01:03 +0000 | [diff] [blame] | 2011 |         // C++ 9.6p3: A bit-field shall not be a static member. | 
 | 2012 |         // "static member 'A' cannot be a bit-field" | 
 | 2013 |         Diag(Loc, diag::err_static_not_bitfield) | 
 | 2014 |           << Name << BitWidth->getSourceRange(); | 
 | 2015 |       } else if (isa<TypedefDecl>(Member)) { | 
 | 2016 |         // "typedef member 'x' cannot be a bit-field" | 
 | 2017 |         Diag(Loc, diag::err_typedef_not_bitfield) | 
 | 2018 |           << Name << BitWidth->getSourceRange(); | 
 | 2019 |       } else { | 
 | 2020 |         // A function typedef ("typedef int f(); f a;"). | 
 | 2021 |         // C++ 9.6p3: A bit-field shall have integral or enumeration type. | 
 | 2022 |         Diag(Loc, diag::err_not_integral_type_bitfield) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2023 |           << Name << cast<ValueDecl>(Member)->getType() | 
| Douglas Gregor | 3cf538d | 2009-03-11 18:59:21 +0000 | [diff] [blame] | 2024 |           << BitWidth->getSourceRange(); | 
| Chris Lattner | 8b963ef | 2009-03-05 23:01:03 +0000 | [diff] [blame] | 2025 |       } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2026 |  | 
| Chris Lattner | 8b963ef | 2009-03-05 23:01:03 +0000 | [diff] [blame] | 2027 |       BitWidth = 0; | 
 | 2028 |       Member->setInvalidDecl(); | 
 | 2029 |     } | 
| Douglas Gregor | 4dd55f5 | 2009-03-11 20:50:30 +0000 | [diff] [blame] | 2030 |  | 
 | 2031 |     Member->setAccess(AS); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2032 |  | 
| Larisse Voufo | ef4579c | 2013-08-06 01:03:05 +0000 | [diff] [blame] | 2033 |     // If we have declared a member function template or static data member | 
 | 2034 |     // template, set the access of the templated declaration as well. | 
| Douglas Gregor | 37b372b | 2009-08-20 22:52:58 +0000 | [diff] [blame] | 2035 |     if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Member)) | 
 | 2036 |       FunTmpl->getTemplatedDecl()->setAccess(AS); | 
| Larisse Voufo | ef4579c | 2013-08-06 01:03:05 +0000 | [diff] [blame] | 2037 |     else if (VarTemplateDecl *VarTmpl = dyn_cast<VarTemplateDecl>(Member)) | 
 | 2038 |       VarTmpl->getTemplatedDecl()->setAccess(AS); | 
| Chris Lattner | 2479366 | 2009-03-05 22:45:59 +0000 | [diff] [blame] | 2039 |   } | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 2040 |  | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 2041 |   if (VS.isOverrideSpecified()) | 
 | 2042 |     Member->addAttr(new (Context) OverrideAttr(VS.getOverrideLoc(), Context)); | 
 | 2043 |   if (VS.isFinalSpecified()) | 
 | 2044 |     Member->addAttr(new (Context) FinalAttr(VS.getFinalLoc(), Context)); | 
| Anders Carlsson | 9e682d9 | 2011-01-20 05:57:14 +0000 | [diff] [blame] | 2045 |  | 
| Douglas Gregor | f525160 | 2011-03-08 17:10:18 +0000 | [diff] [blame] | 2046 |   if (VS.getLastLocation().isValid()) { | 
 | 2047 |     // Update the end location of a method that has a virt-specifiers. | 
 | 2048 |     if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Member)) | 
 | 2049 |       MD->setRangeEnd(VS.getLastLocation()); | 
 | 2050 |   } | 
| Richard Smith | a4b3965 | 2012-08-06 03:25:17 +0000 | [diff] [blame] | 2051 |  | 
| Anders Carlsson | 4ebf160 | 2011-01-20 06:29:02 +0000 | [diff] [blame] | 2052 |   CheckOverrideControl(Member); | 
| Anders Carlsson | 9e682d9 | 2011-01-20 05:57:14 +0000 | [diff] [blame] | 2053 |  | 
| Douglas Gregor | 10bd368 | 2008-11-17 22:58:34 +0000 | [diff] [blame] | 2054 |   assert((Name || isInstField) && "No identifier for non-field ?"); | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 2055 |  | 
| Daniel Jasper | f8cc02e | 2012-06-06 08:32:04 +0000 | [diff] [blame] | 2056 |   if (isInstField) { | 
 | 2057 |     FieldDecl *FD = cast<FieldDecl>(Member); | 
 | 2058 |     FieldCollector->Add(FD); | 
 | 2059 |  | 
 | 2060 |     if (Diags.getDiagnosticLevel(diag::warn_unused_private_field, | 
 | 2061 |                                  FD->getLocation()) | 
 | 2062 |           != DiagnosticsEngine::Ignored) { | 
 | 2063 |       // Remember all explicit private FieldDecls that have a name, no side | 
 | 2064 |       // effects and are not part of a dependent type declaration. | 
 | 2065 |       if (!FD->isImplicit() && FD->getDeclName() && | 
 | 2066 |           FD->getAccess() == AS_private && | 
| Daniel Jasper | 568eae4 | 2012-06-13 18:31:09 +0000 | [diff] [blame] | 2067 |           !FD->hasAttr<UnusedAttr>() && | 
| Richard Smith | 0b8220a | 2012-08-07 21:30:42 +0000 | [diff] [blame] | 2068 |           !FD->getParent()->isDependentContext() && | 
| Daniel Jasper | f8cc02e | 2012-06-06 08:32:04 +0000 | [diff] [blame] | 2069 |           !InitializationHasSideEffects(*FD)) | 
 | 2070 |         UnusedPrivateFields.insert(FD); | 
 | 2071 |     } | 
 | 2072 |   } | 
 | 2073 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 2074 |   return Member; | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 2075 | } | 
 | 2076 |  | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2077 | namespace { | 
 | 2078 |   class UninitializedFieldVisitor | 
 | 2079 |       : public EvaluatedExprVisitor<UninitializedFieldVisitor> { | 
 | 2080 |     Sema &S; | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2081 |     // If VD is null, this visitor will only update the Decls set. | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2082 |     ValueDecl *VD; | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2083 |     bool isReferenceType; | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2084 |     // List of Decls to generate a warning on. | 
 | 2085 |     llvm::SmallPtrSet<ValueDecl*, 4> &Decls; | 
 | 2086 |     bool WarnOnSelfReference; | 
 | 2087 |     // If non-null, add a note to the warning pointing back to the constructor. | 
 | 2088 |     const CXXConstructorDecl *Constructor; | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2089 |   public: | 
 | 2090 |     typedef EvaluatedExprVisitor<UninitializedFieldVisitor> Inherited; | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2091 |     UninitializedFieldVisitor(Sema &S, ValueDecl *VD, | 
 | 2092 |                               llvm::SmallPtrSet<ValueDecl*, 4> &Decls, | 
 | 2093 |                               bool WarnOnSelfReference, | 
 | 2094 |                               const CXXConstructorDecl *Constructor) | 
 | 2095 |       : Inherited(S.Context), S(S), VD(VD), isReferenceType(false), Decls(Decls), | 
 | 2096 |         WarnOnSelfReference(WarnOnSelfReference), Constructor(Constructor) { | 
 | 2097 |       // When VD is null, this visitor is used to detect initialization of other | 
 | 2098 |       // fields. | 
 | 2099 |       if (VD) { | 
 | 2100 |         if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(VD)) | 
 | 2101 |           this->VD = IFD->getAnonField(); | 
 | 2102 |         else | 
 | 2103 |           this->VD = VD; | 
 | 2104 |         isReferenceType = this->VD->getType()->isReferenceType(); | 
 | 2105 |       } | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2106 |     } | 
 | 2107 |  | 
| Richard Trieu | 3ddec88 | 2013-09-16 20:46:50 +0000 | [diff] [blame] | 2108 |     void HandleMemberExpr(MemberExpr *ME, bool CheckReferenceOnly) { | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2109 |       if (!VD) | 
 | 2110 |         return; | 
 | 2111 |  | 
| Richard Trieu | 3ddec88 | 2013-09-16 20:46:50 +0000 | [diff] [blame] | 2112 |       if (CheckReferenceOnly && !isReferenceType) | 
 | 2113 |         return; | 
 | 2114 |  | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2115 |       if (isa<EnumConstantDecl>(ME->getMemberDecl())) | 
 | 2116 |         return; | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2117 |  | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2118 |       // FieldME is the inner-most MemberExpr that is not an anonymous struct | 
 | 2119 |       // or union. | 
 | 2120 |       MemberExpr *FieldME = ME; | 
 | 2121 |  | 
 | 2122 |       Expr *Base = ME; | 
 | 2123 |       while (isa<MemberExpr>(Base)) { | 
 | 2124 |         ME = cast<MemberExpr>(Base); | 
 | 2125 |  | 
 | 2126 |         if (isa<VarDecl>(ME->getMemberDecl())) | 
 | 2127 |           return; | 
 | 2128 |  | 
 | 2129 |         if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) | 
 | 2130 |           if (!FD->isAnonymousStructOrUnion()) | 
 | 2131 |             FieldME = ME; | 
 | 2132 |  | 
 | 2133 |         Base = ME->getBase(); | 
 | 2134 |       } | 
 | 2135 |  | 
| Richard Trieu | 3ddec88 | 2013-09-16 20:46:50 +0000 | [diff] [blame] | 2136 |       if (!isa<CXXThisExpr>(Base)) | 
 | 2137 |         return; | 
 | 2138 |  | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2139 |       ValueDecl* FoundVD = FieldME->getMemberDecl(); | 
 | 2140 |  | 
 | 2141 |       if (VD == FoundVD) { | 
 | 2142 |         if (!WarnOnSelfReference) | 
 | 2143 |           return; | 
 | 2144 |  | 
| Richard Trieu | 3ddec88 | 2013-09-16 20:46:50 +0000 | [diff] [blame] | 2145 |         unsigned diag = isReferenceType | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2146 |             ? diag::warn_reference_field_is_uninit | 
 | 2147 |             : diag::warn_field_is_uninit; | 
 | 2148 |         S.Diag(FieldME->getExprLoc(), diag) << VD; | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2149 |         if (Constructor) | 
 | 2150 |           S.Diag(Constructor->getLocation(), | 
 | 2151 |                  diag::note_uninit_in_this_constructor); | 
 | 2152 |         return; | 
 | 2153 |       } | 
 | 2154 |  | 
 | 2155 |       if (CheckReferenceOnly) | 
 | 2156 |         return; | 
 | 2157 |  | 
 | 2158 |       if (Decls.count(FoundVD)) { | 
 | 2159 |         S.Diag(FieldME->getExprLoc(), diag::warn_field_is_uninit) << FoundVD; | 
 | 2160 |         if (Constructor) | 
 | 2161 |           S.Diag(Constructor->getLocation(), | 
 | 2162 |                  diag::note_uninit_in_this_constructor); | 
 | 2163 |  | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2164 |       } | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2165 |     } | 
 | 2166 |  | 
 | 2167 |     void HandleValue(Expr *E) { | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2168 |       if (!VD) | 
 | 2169 |         return; | 
 | 2170 |  | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2171 |       E = E->IgnoreParens(); | 
 | 2172 |  | 
 | 2173 |       if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { | 
| Richard Trieu | 3ddec88 | 2013-09-16 20:46:50 +0000 | [diff] [blame] | 2174 |         HandleMemberExpr(ME, false /*CheckReferenceOnly*/); | 
| Nick Lewycky | 621ba4f | 2012-11-15 08:19:20 +0000 | [diff] [blame] | 2175 |         return; | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2176 |       } | 
 | 2177 |  | 
 | 2178 |       if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { | 
 | 2179 |         HandleValue(CO->getTrueExpr()); | 
 | 2180 |         HandleValue(CO->getFalseExpr()); | 
 | 2181 |         return; | 
 | 2182 |       } | 
 | 2183 |  | 
 | 2184 |       if (BinaryConditionalOperator *BCO = | 
 | 2185 |               dyn_cast<BinaryConditionalOperator>(E)) { | 
 | 2186 |         HandleValue(BCO->getCommon()); | 
 | 2187 |         HandleValue(BCO->getFalseExpr()); | 
 | 2188 |         return; | 
 | 2189 |       } | 
 | 2190 |  | 
 | 2191 |       if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { | 
 | 2192 |         switch (BO->getOpcode()) { | 
 | 2193 |         default: | 
 | 2194 |           return; | 
 | 2195 |         case(BO_PtrMemD): | 
 | 2196 |         case(BO_PtrMemI): | 
 | 2197 |           HandleValue(BO->getLHS()); | 
 | 2198 |           return; | 
 | 2199 |         case(BO_Comma): | 
 | 2200 |           HandleValue(BO->getRHS()); | 
 | 2201 |           return; | 
 | 2202 |         } | 
 | 2203 |       } | 
 | 2204 |     } | 
 | 2205 |  | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2206 |     void VisitMemberExpr(MemberExpr *ME) { | 
| Richard Trieu | 3ddec88 | 2013-09-16 20:46:50 +0000 | [diff] [blame] | 2207 |       HandleMemberExpr(ME, true /*CheckReferenceOnly*/); | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2208 |  | 
 | 2209 |       Inherited::VisitMemberExpr(ME); | 
 | 2210 |     } | 
 | 2211 |  | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2212 |     void VisitImplicitCastExpr(ImplicitCastExpr *E) { | 
 | 2213 |       if (E->getCastKind() == CK_LValueToRValue) | 
 | 2214 |         HandleValue(E->getSubExpr()); | 
 | 2215 |  | 
 | 2216 |       Inherited::VisitImplicitCastExpr(E); | 
 | 2217 |     } | 
 | 2218 |  | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2219 |     void VisitCXXConstructExpr(CXXConstructExpr *E) { | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2220 |       if (E->getConstructor()->isCopyConstructor()) | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2221 |         if (ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(E->getArg(0))) | 
 | 2222 |           if (ICE->getCastKind() == CK_NoOp) | 
 | 2223 |             if (MemberExpr *ME = dyn_cast<MemberExpr>(ICE->getSubExpr())) | 
| Richard Trieu | 3ddec88 | 2013-09-16 20:46:50 +0000 | [diff] [blame] | 2224 |               HandleMemberExpr(ME, false /*CheckReferenceOnly*/); | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2225 |        | 
 | 2226 |       Inherited::VisitCXXConstructExpr(E); | 
 | 2227 |     } | 
 | 2228 |  | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2229 |     void VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { | 
 | 2230 |       Expr *Callee = E->getCallee(); | 
 | 2231 |       if (isa<MemberExpr>(Callee)) | 
 | 2232 |         HandleValue(Callee); | 
 | 2233 |  | 
 | 2234 |       Inherited::VisitCXXMemberCallExpr(E); | 
 | 2235 |     } | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2236 |  | 
 | 2237 |     void VisitBinaryOperator(BinaryOperator *E) { | 
 | 2238 |       // If a field assignment is detected, remove the field from the | 
 | 2239 |       // uninitiailized field set. | 
 | 2240 |       if (E->getOpcode() == BO_Assign) | 
 | 2241 |         if (MemberExpr *ME = dyn_cast<MemberExpr>(E->getLHS())) | 
 | 2242 |           if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) | 
 | 2243 |             Decls.erase(FD); | 
 | 2244 |  | 
 | 2245 |       Inherited::VisitBinaryOperator(E); | 
 | 2246 |     } | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2247 |   }; | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2248 |   static void CheckInitExprContainsUninitializedFields( | 
 | 2249 |       Sema &S, Expr *E, ValueDecl *VD, llvm::SmallPtrSet<ValueDecl*, 4> &Decls, | 
 | 2250 |       bool WarnOnSelfReference, const CXXConstructorDecl *Constructor = 0) { | 
 | 2251 |     if (Decls.size() == 0 && !WarnOnSelfReference) | 
 | 2252 |       return; | 
 | 2253 |  | 
| Richard Trieu | fbb08b5 | 2013-09-13 03:20:53 +0000 | [diff] [blame] | 2254 |     if (E) | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 2255 |       UninitializedFieldVisitor(S, VD, Decls, WarnOnSelfReference, Constructor) | 
 | 2256 |           .Visit(E); | 
| Hans Wennborg | 471f985 | 2012-09-18 15:58:06 +0000 | [diff] [blame] | 2257 |   } | 
 | 2258 | } // namespace | 
 | 2259 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2260 | /// ActOnCXXInClassMemberInitializer - This is invoked after parsing an | 
| Richard Smith | 0ff6f8f | 2011-07-20 00:12:52 +0000 | [diff] [blame] | 2261 | /// in-class initializer for a non-static C++ class member, and after | 
 | 2262 | /// instantiating an in-class initializer in a class template. Such actions | 
 | 2263 | /// are deferred until the class is complete. | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2264 | void | 
| Richard Smith | ca52330 | 2012-06-10 03:12:00 +0000 | [diff] [blame] | 2265 | Sema::ActOnCXXInClassMemberInitializer(Decl *D, SourceLocation InitLoc, | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2266 |                                        Expr *InitExpr) { | 
 | 2267 |   FieldDecl *FD = cast<FieldDecl>(D); | 
| Richard Smith | ca52330 | 2012-06-10 03:12:00 +0000 | [diff] [blame] | 2268 |   assert(FD->getInClassInitStyle() != ICIS_NoInit && | 
 | 2269 |          "must set init style when field is created"); | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2270 |  | 
 | 2271 |   if (!InitExpr) { | 
 | 2272 |     FD->setInvalidDecl(); | 
 | 2273 |     FD->removeInClassInitializer(); | 
 | 2274 |     return; | 
 | 2275 |   } | 
 | 2276 |  | 
| Peter Collingbourne | fef2189 | 2011-10-23 18:59:44 +0000 | [diff] [blame] | 2277 |   if (DiagnoseUnexpandedParameterPack(InitExpr, UPPC_Initializer)) { | 
 | 2278 |     FD->setInvalidDecl(); | 
 | 2279 |     FD->removeInClassInitializer(); | 
 | 2280 |     return; | 
 | 2281 |   } | 
 | 2282 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2283 |   ExprResult Init = InitExpr; | 
| Richard Smith | c83c230 | 2012-12-19 01:39:02 +0000 | [diff] [blame] | 2284 |   if (!FD->getType()->isDependentType() && !InitExpr->isTypeDependent()) { | 
| Sebastian Redl | 33deb35 | 2012-02-22 10:50:08 +0000 | [diff] [blame] | 2285 |     InitializedEntity Entity = InitializedEntity::InitializeMember(FD); | 
| Richard Smith | ca52330 | 2012-06-10 03:12:00 +0000 | [diff] [blame] | 2286 |     InitializationKind Kind = FD->getInClassInitStyle() == ICIS_ListInit | 
| Sebastian Redl | 33deb35 | 2012-02-22 10:50:08 +0000 | [diff] [blame] | 2287 |         ? InitializationKind::CreateDirectList(InitExpr->getLocStart()) | 
| Richard Smith | ca52330 | 2012-06-10 03:12:00 +0000 | [diff] [blame] | 2288 |         : InitializationKind::CreateCopy(InitExpr->getLocStart(), InitLoc); | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2289 |     InitializationSequence Seq(*this, Entity, Kind, InitExpr); | 
 | 2290 |     Init = Seq.Perform(*this, Entity, Kind, InitExpr); | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2291 |     if (Init.isInvalid()) { | 
 | 2292 |       FD->setInvalidDecl(); | 
 | 2293 |       return; | 
 | 2294 |     } | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2295 |   } | 
 | 2296 |  | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 2297 |   // C++11 [class.base.init]p7: | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2298 |   //   The initialization of each base and member constitutes a | 
 | 2299 |   //   full-expression. | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 2300 |   Init = ActOnFinishFullExpr(Init.take(), InitLoc); | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2301 |   if (Init.isInvalid()) { | 
 | 2302 |     FD->setInvalidDecl(); | 
 | 2303 |     return; | 
 | 2304 |   } | 
 | 2305 |  | 
 | 2306 |   InitExpr = Init.release(); | 
 | 2307 |  | 
 | 2308 |   FD->setInClassInitializer(InitExpr); | 
 | 2309 | } | 
 | 2310 |  | 
| Douglas Gregor | fe0241e | 2009-12-31 09:10:24 +0000 | [diff] [blame] | 2311 | /// \brief Find the direct and/or virtual base specifiers that | 
 | 2312 | /// correspond to the given base type, for use in base initialization | 
 | 2313 | /// within a constructor. | 
 | 2314 | static bool FindBaseInitializer(Sema &SemaRef,  | 
 | 2315 |                                 CXXRecordDecl *ClassDecl, | 
 | 2316 |                                 QualType BaseType, | 
 | 2317 |                                 const CXXBaseSpecifier *&DirectBaseSpec, | 
 | 2318 |                                 const CXXBaseSpecifier *&VirtualBaseSpec) { | 
 | 2319 |   // First, check for a direct base class. | 
 | 2320 |   DirectBaseSpec = 0; | 
 | 2321 |   for (CXXRecordDecl::base_class_const_iterator Base | 
 | 2322 |          = ClassDecl->bases_begin();  | 
 | 2323 |        Base != ClassDecl->bases_end(); ++Base) { | 
 | 2324 |     if (SemaRef.Context.hasSameUnqualifiedType(BaseType, Base->getType())) { | 
 | 2325 |       // We found a direct base of this type. That's what we're | 
 | 2326 |       // initializing. | 
 | 2327 |       DirectBaseSpec = &*Base; | 
 | 2328 |       break; | 
 | 2329 |     } | 
 | 2330 |   } | 
 | 2331 |  | 
 | 2332 |   // Check for a virtual base class. | 
 | 2333 |   // FIXME: We might be able to short-circuit this if we know in advance that | 
 | 2334 |   // there are no virtual bases. | 
 | 2335 |   VirtualBaseSpec = 0; | 
 | 2336 |   if (!DirectBaseSpec || !DirectBaseSpec->isVirtual()) { | 
 | 2337 |     // We haven't found a base yet; search the class hierarchy for a | 
 | 2338 |     // virtual base class. | 
 | 2339 |     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | 
 | 2340 |                        /*DetectVirtual=*/false); | 
 | 2341 |     if (SemaRef.IsDerivedFrom(SemaRef.Context.getTypeDeclType(ClassDecl),  | 
 | 2342 |                               BaseType, Paths)) { | 
 | 2343 |       for (CXXBasePaths::paths_iterator Path = Paths.begin(); | 
 | 2344 |            Path != Paths.end(); ++Path) { | 
 | 2345 |         if (Path->back().Base->isVirtual()) { | 
 | 2346 |           VirtualBaseSpec = Path->back().Base; | 
 | 2347 |           break; | 
 | 2348 |         } | 
 | 2349 |       } | 
 | 2350 |     } | 
 | 2351 |   } | 
 | 2352 |  | 
 | 2353 |   return DirectBaseSpec || VirtualBaseSpec; | 
 | 2354 | } | 
 | 2355 |  | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2356 | /// \brief Handle a C++ member initializer using braced-init-list syntax. | 
 | 2357 | MemInitResult | 
 | 2358 | Sema::ActOnMemInitializer(Decl *ConstructorD, | 
 | 2359 |                           Scope *S, | 
 | 2360 |                           CXXScopeSpec &SS, | 
 | 2361 |                           IdentifierInfo *MemberOrBase, | 
 | 2362 |                           ParsedType TemplateTypeTy, | 
| David Blaikie | f211662 | 2012-01-24 06:03:59 +0000 | [diff] [blame] | 2363 |                           const DeclSpec &DS, | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2364 |                           SourceLocation IdLoc, | 
 | 2365 |                           Expr *InitList, | 
 | 2366 |                           SourceLocation EllipsisLoc) { | 
 | 2367 |   return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy, | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2368 |                              DS, IdLoc, InitList, | 
| David Blaikie | f211662 | 2012-01-24 06:03:59 +0000 | [diff] [blame] | 2369 |                              EllipsisLoc); | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2370 | } | 
 | 2371 |  | 
 | 2372 | /// \brief Handle a C++ member initializer using parentheses syntax. | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 2373 | MemInitResult | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 2374 | Sema::ActOnMemInitializer(Decl *ConstructorD, | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2375 |                           Scope *S, | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 2376 |                           CXXScopeSpec &SS, | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2377 |                           IdentifierInfo *MemberOrBase, | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 2378 |                           ParsedType TemplateTypeTy, | 
| David Blaikie | f211662 | 2012-01-24 06:03:59 +0000 | [diff] [blame] | 2379 |                           const DeclSpec &DS, | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2380 |                           SourceLocation IdLoc, | 
 | 2381 |                           SourceLocation LParenLoc, | 
| Dmitri Gribenko | a36bbac | 2013-05-09 23:51:52 +0000 | [diff] [blame] | 2382 |                           ArrayRef<Expr *> Args, | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2383 |                           SourceLocation RParenLoc, | 
 | 2384 |                           SourceLocation EllipsisLoc) { | 
| Benjamin Kramer | 3b6bef9 | 2012-08-24 11:54:20 +0000 | [diff] [blame] | 2385 |   Expr *List = new (Context) ParenListExpr(Context, LParenLoc, | 
| Dmitri Gribenko | a36bbac | 2013-05-09 23:51:52 +0000 | [diff] [blame] | 2386 |                                            Args, RParenLoc); | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2387 |   return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy, | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2388 |                              DS, IdLoc, List, EllipsisLoc); | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2389 | } | 
 | 2390 |  | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 2391 | namespace { | 
 | 2392 |  | 
| Kaelyn Uhrain | dc98cd0 | 2012-01-11 21:17:51 +0000 | [diff] [blame] | 2393 | // Callback to only accept typo corrections that can be a valid C++ member | 
 | 2394 | // intializer: either a non-static field member or a base class. | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 2395 | class MemInitializerValidatorCCC : public CorrectionCandidateCallback { | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 2396 | public: | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 2397 |   explicit MemInitializerValidatorCCC(CXXRecordDecl *ClassDecl) | 
 | 2398 |       : ClassDecl(ClassDecl) {} | 
 | 2399 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 2400 |   bool ValidateCandidate(const TypoCorrection &candidate) LLVM_OVERRIDE { | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 2401 |     if (NamedDecl *ND = candidate.getCorrectionDecl()) { | 
 | 2402 |       if (FieldDecl *Member = dyn_cast<FieldDecl>(ND)) | 
 | 2403 |         return Member->getDeclContext()->getRedeclContext()->Equals(ClassDecl); | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 2404 |       return isa<TypeDecl>(ND); | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 2405 |     } | 
 | 2406 |     return false; | 
 | 2407 |   } | 
 | 2408 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 2409 | private: | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 2410 |   CXXRecordDecl *ClassDecl; | 
 | 2411 | }; | 
 | 2412 |  | 
 | 2413 | } | 
 | 2414 |  | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2415 | /// \brief Handle a C++ member initializer. | 
 | 2416 | MemInitResult | 
 | 2417 | Sema::BuildMemInitializer(Decl *ConstructorD, | 
 | 2418 |                           Scope *S, | 
 | 2419 |                           CXXScopeSpec &SS, | 
 | 2420 |                           IdentifierInfo *MemberOrBase, | 
 | 2421 |                           ParsedType TemplateTypeTy, | 
| David Blaikie | f211662 | 2012-01-24 06:03:59 +0000 | [diff] [blame] | 2422 |                           const DeclSpec &DS, | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2423 |                           SourceLocation IdLoc, | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2424 |                           Expr *Init, | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2425 |                           SourceLocation EllipsisLoc) { | 
| Douglas Gregor | 4c4f7cb | 2009-06-22 23:20:33 +0000 | [diff] [blame] | 2426 |   if (!ConstructorD) | 
 | 2427 |     return true; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2428 |  | 
| Douglas Gregor | efd5bda | 2009-08-24 11:57:43 +0000 | [diff] [blame] | 2429 |   AdjustDeclIfTemplate(ConstructorD); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2430 |  | 
 | 2431 |   CXXConstructorDecl *Constructor | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 2432 |     = dyn_cast<CXXConstructorDecl>(ConstructorD); | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2433 |   if (!Constructor) { | 
 | 2434 |     // The user wrote a constructor initializer on a function that is | 
 | 2435 |     // not a C++ constructor. Ignore the error for now, because we may | 
 | 2436 |     // have more member initializers coming; we'll diagnose it just | 
 | 2437 |     // once in ActOnMemInitializers. | 
 | 2438 |     return true; | 
 | 2439 |   } | 
 | 2440 |  | 
 | 2441 |   CXXRecordDecl *ClassDecl = Constructor->getParent(); | 
 | 2442 |  | 
 | 2443 |   // C++ [class.base.init]p2: | 
 | 2444 |   //   Names in a mem-initializer-id are looked up in the scope of the | 
| Nick Lewycky | 7663f39 | 2010-11-20 01:29:55 +0000 | [diff] [blame] | 2445 |   //   constructor's class and, if not found in that scope, are looked | 
 | 2446 |   //   up in the scope containing the constructor's definition. | 
 | 2447 |   //   [Note: if the constructor's class contains a member with the | 
 | 2448 |   //   same name as a direct or virtual base class of the class, a | 
 | 2449 |   //   mem-initializer-id naming the member or base class and composed | 
 | 2450 |   //   of a single identifier refers to the class member. A | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2451 |   //   mem-initializer-id for the hidden base class may be specified | 
 | 2452 |   //   using a qualified name. ] | 
| Fariborz Jahanian | 9617433 | 2009-07-01 19:21:19 +0000 | [diff] [blame] | 2453 |   if (!SS.getScopeRep() && !TemplateTypeTy) { | 
| Fariborz Jahanian | bcfad54 | 2009-06-30 23:26:25 +0000 | [diff] [blame] | 2454 |     // Look for a member, first. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2455 |     DeclContext::lookup_result Result | 
| Fariborz Jahanian | bcfad54 | 2009-06-30 23:26:25 +0000 | [diff] [blame] | 2456 |       = ClassDecl->lookup(MemberOrBase); | 
| David Blaikie | 3bc93e3 | 2012-12-19 00:45:41 +0000 | [diff] [blame] | 2457 |     if (!Result.empty()) { | 
| Peter Collingbourne | dc69be2 | 2011-10-23 18:59:37 +0000 | [diff] [blame] | 2458 |       ValueDecl *Member; | 
| David Blaikie | 3bc93e3 | 2012-12-19 00:45:41 +0000 | [diff] [blame] | 2459 |       if ((Member = dyn_cast<FieldDecl>(Result.front())) || | 
 | 2460 |           (Member = dyn_cast<IndirectFieldDecl>(Result.front()))) { | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2461 |         if (EllipsisLoc.isValid()) | 
 | 2462 |           Diag(EllipsisLoc, diag::err_pack_expansion_member_init) | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2463 |             << MemberOrBase | 
 | 2464 |             << SourceRange(IdLoc, Init->getSourceRange().getEnd()); | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2465 |  | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2466 |         return BuildMemberInitializer(Member, Init, IdLoc); | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2467 |       } | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 2468 |     } | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2469 |   } | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2470 |   // It didn't name a member, so see if it names a class. | 
| Douglas Gregor | 802ab45 | 2009-12-02 22:36:29 +0000 | [diff] [blame] | 2471 |   QualType BaseType; | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2472 |   TypeSourceInfo *TInfo = 0; | 
| John McCall | 2b19441 | 2009-12-21 10:41:20 +0000 | [diff] [blame] | 2473 |  | 
 | 2474 |   if (TemplateTypeTy) { | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2475 |     BaseType = GetTypeFromParser(TemplateTypeTy, &TInfo); | 
| David Blaikie | f211662 | 2012-01-24 06:03:59 +0000 | [diff] [blame] | 2476 |   } else if (DS.getTypeSpecType() == TST_decltype) { | 
 | 2477 |     BaseType = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); | 
| John McCall | 2b19441 | 2009-12-21 10:41:20 +0000 | [diff] [blame] | 2478 |   } else { | 
 | 2479 |     LookupResult R(*this, MemberOrBase, IdLoc, LookupOrdinaryName); | 
 | 2480 |     LookupParsedName(R, S, &SS); | 
 | 2481 |  | 
 | 2482 |     TypeDecl *TyD = R.getAsSingle<TypeDecl>(); | 
 | 2483 |     if (!TyD) { | 
 | 2484 |       if (R.isAmbiguous()) return true; | 
 | 2485 |  | 
| John McCall | fd22544 | 2010-04-09 19:01:14 +0000 | [diff] [blame] | 2486 |       // We don't want access-control diagnostics here. | 
 | 2487 |       R.suppressDiagnostics(); | 
 | 2488 |  | 
| Douglas Gregor | 7a886e1 | 2010-01-19 06:46:48 +0000 | [diff] [blame] | 2489 |       if (SS.isSet() && isDependentScopeSpecifier(SS)) { | 
 | 2490 |         bool NotUnknownSpecialization = false; | 
 | 2491 |         DeclContext *DC = computeDeclContext(SS, false); | 
 | 2492 |         if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(DC))  | 
 | 2493 |           NotUnknownSpecialization = !Record->hasAnyDependentBases(); | 
 | 2494 |  | 
 | 2495 |         if (!NotUnknownSpecialization) { | 
 | 2496 |           // When the scope specifier can refer to a member of an unknown | 
 | 2497 |           // specialization, we take it as a type name. | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 2498 |           BaseType = CheckTypenameType(ETK_None, SourceLocation(), | 
 | 2499 |                                        SS.getWithLocInContext(Context), | 
 | 2500 |                                        *MemberOrBase, IdLoc); | 
| Douglas Gregor | a50ce32 | 2010-03-07 23:26:22 +0000 | [diff] [blame] | 2501 |           if (BaseType.isNull()) | 
 | 2502 |             return true; | 
 | 2503 |  | 
| Douglas Gregor | 7a886e1 | 2010-01-19 06:46:48 +0000 | [diff] [blame] | 2504 |           R.clear(); | 
| Douglas Gregor | 12eb5d6 | 2010-06-29 19:27:42 +0000 | [diff] [blame] | 2505 |           R.setLookupName(MemberOrBase); | 
| Douglas Gregor | 7a886e1 | 2010-01-19 06:46:48 +0000 | [diff] [blame] | 2506 |         } | 
 | 2507 |       } | 
 | 2508 |  | 
| Douglas Gregor | fe0241e | 2009-12-31 09:10:24 +0000 | [diff] [blame] | 2509 |       // If no results were found, try to correct typos. | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 2510 |       TypoCorrection Corr; | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 2511 |       MemInitializerValidatorCCC Validator(ClassDecl); | 
| Douglas Gregor | 7a886e1 | 2010-01-19 06:46:48 +0000 | [diff] [blame] | 2512 |       if (R.empty() && BaseType.isNull() && | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 2513 |           (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, | 
| Kaelyn Uhrain | 16e46dd | 2012-01-31 23:49:25 +0000 | [diff] [blame] | 2514 |                               Validator, ClassDecl))) { | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 2515 |         if (FieldDecl *Member = Corr.getCorrectionDeclAs<FieldDecl>()) { | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 2516 |           // We have found a non-static data member with a similar | 
 | 2517 |           // name to what was typed; complain and initialize that | 
 | 2518 |           // member. | 
| Richard Smith | 2d67097 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 2519 |           diagnoseTypo(Corr, | 
 | 2520 |                        PDiag(diag::err_mem_init_not_member_or_class_suggest) | 
 | 2521 |                          << MemberOrBase << true); | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2522 |           return BuildMemberInitializer(Member, Init, IdLoc); | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 2523 |         } else if (TypeDecl *Type = Corr.getCorrectionDeclAs<TypeDecl>()) { | 
| Douglas Gregor | fe0241e | 2009-12-31 09:10:24 +0000 | [diff] [blame] | 2524 |           const CXXBaseSpecifier *DirectBaseSpec; | 
 | 2525 |           const CXXBaseSpecifier *VirtualBaseSpec; | 
 | 2526 |           if (FindBaseInitializer(*this, ClassDecl,  | 
 | 2527 |                                   Context.getTypeDeclType(Type), | 
 | 2528 |                                   DirectBaseSpec, VirtualBaseSpec)) { | 
 | 2529 |             // We have found a direct or virtual base class with a | 
 | 2530 |             // similar name to what was typed; complain and initialize | 
 | 2531 |             // that base class. | 
| Richard Smith | 2d67097 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 2532 |             diagnoseTypo(Corr, | 
 | 2533 |                          PDiag(diag::err_mem_init_not_member_or_class_suggest) | 
 | 2534 |                            << MemberOrBase << false, | 
 | 2535 |                          PDiag() /*Suppress note, we provide our own.*/); | 
| Douglas Gregor | 0d535c8 | 2010-01-07 00:26:25 +0000 | [diff] [blame] | 2536 |  | 
| Richard Smith | 2d67097 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 2537 |             const CXXBaseSpecifier *BaseSpec = DirectBaseSpec ? DirectBaseSpec | 
 | 2538 |                                                               : VirtualBaseSpec; | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 2539 |             Diag(BaseSpec->getLocStart(), | 
| Douglas Gregor | 0d535c8 | 2010-01-07 00:26:25 +0000 | [diff] [blame] | 2540 |                  diag::note_base_class_specified_here) | 
 | 2541 |               << BaseSpec->getType() | 
 | 2542 |               << BaseSpec->getSourceRange(); | 
 | 2543 |  | 
| Douglas Gregor | fe0241e | 2009-12-31 09:10:24 +0000 | [diff] [blame] | 2544 |             TyD = Type; | 
 | 2545 |           } | 
 | 2546 |         } | 
 | 2547 |       } | 
 | 2548 |  | 
| Douglas Gregor | 7a886e1 | 2010-01-19 06:46:48 +0000 | [diff] [blame] | 2549 |       if (!TyD && BaseType.isNull()) { | 
| Douglas Gregor | fe0241e | 2009-12-31 09:10:24 +0000 | [diff] [blame] | 2550 |         Diag(IdLoc, diag::err_mem_init_not_member_or_class) | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2551 |           << MemberOrBase << SourceRange(IdLoc,Init->getSourceRange().getEnd()); | 
| Douglas Gregor | fe0241e | 2009-12-31 09:10:24 +0000 | [diff] [blame] | 2552 |         return true; | 
 | 2553 |       } | 
| John McCall | 2b19441 | 2009-12-21 10:41:20 +0000 | [diff] [blame] | 2554 |     } | 
 | 2555 |  | 
| Douglas Gregor | 7a886e1 | 2010-01-19 06:46:48 +0000 | [diff] [blame] | 2556 |     if (BaseType.isNull()) { | 
 | 2557 |       BaseType = Context.getTypeDeclType(TyD); | 
 | 2558 |       if (SS.isSet()) { | 
 | 2559 |         NestedNameSpecifier *Qualifier = | 
 | 2560 |           static_cast<NestedNameSpecifier*>(SS.getScopeRep()); | 
| John McCall | 2b19441 | 2009-12-21 10:41:20 +0000 | [diff] [blame] | 2561 |  | 
| Douglas Gregor | 7a886e1 | 2010-01-19 06:46:48 +0000 | [diff] [blame] | 2562 |         // FIXME: preserve source range information | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 2563 |         BaseType = Context.getElaboratedType(ETK_None, Qualifier, BaseType); | 
| Douglas Gregor | 7a886e1 | 2010-01-19 06:46:48 +0000 | [diff] [blame] | 2564 |       } | 
| John McCall | 2b19441 | 2009-12-21 10:41:20 +0000 | [diff] [blame] | 2565 |     } | 
 | 2566 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2567 |  | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2568 |   if (!TInfo) | 
 | 2569 |     TInfo = Context.getTrivialTypeSourceInfo(BaseType, IdLoc); | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2570 |  | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2571 |   return BuildBaseInitializer(BaseType, TInfo, Init, ClassDecl, EllipsisLoc); | 
| Eli Friedman | 59c0437 | 2009-07-29 19:44:27 +0000 | [diff] [blame] | 2572 | } | 
 | 2573 |  | 
| Chandler Carruth | 81c6477 | 2011-09-03 01:14:15 +0000 | [diff] [blame] | 2574 | /// Checks a member initializer expression for cases where reference (or | 
 | 2575 | /// pointer) members are bound to by-value parameters (or their addresses). | 
| Chandler Carruth | 81c6477 | 2011-09-03 01:14:15 +0000 | [diff] [blame] | 2576 | static void CheckForDanglingReferenceOrPointer(Sema &S, ValueDecl *Member, | 
 | 2577 |                                                Expr *Init, | 
 | 2578 |                                                SourceLocation IdLoc) { | 
 | 2579 |   QualType MemberTy = Member->getType(); | 
 | 2580 |  | 
 | 2581 |   // We only handle pointers and references currently. | 
 | 2582 |   // FIXME: Would this be relevant for ObjC object pointers? Or block pointers? | 
 | 2583 |   if (!MemberTy->isReferenceType() && !MemberTy->isPointerType()) | 
 | 2584 |     return; | 
 | 2585 |  | 
 | 2586 |   const bool IsPointer = MemberTy->isPointerType(); | 
 | 2587 |   if (IsPointer) { | 
 | 2588 |     if (const UnaryOperator *Op | 
 | 2589 |           = dyn_cast<UnaryOperator>(Init->IgnoreParenImpCasts())) { | 
 | 2590 |       // The only case we're worried about with pointers requires taking the | 
 | 2591 |       // address. | 
 | 2592 |       if (Op->getOpcode() != UO_AddrOf) | 
 | 2593 |         return; | 
 | 2594 |  | 
 | 2595 |       Init = Op->getSubExpr(); | 
 | 2596 |     } else { | 
 | 2597 |       // We only handle address-of expression initializers for pointers. | 
 | 2598 |       return; | 
 | 2599 |     } | 
 | 2600 |   } | 
 | 2601 |  | 
| Richard Smith | a4bb99c | 2013-06-12 21:51:50 +0000 | [diff] [blame] | 2602 |   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Init->IgnoreParens())) { | 
| Chandler Carruth | bf3380a | 2011-09-03 02:21:57 +0000 | [diff] [blame] | 2603 |     // We only warn when referring to a non-reference parameter declaration. | 
 | 2604 |     const ParmVarDecl *Parameter = dyn_cast<ParmVarDecl>(DRE->getDecl()); | 
 | 2605 |     if (!Parameter || Parameter->getType()->isReferenceType()) | 
| Chandler Carruth | 81c6477 | 2011-09-03 01:14:15 +0000 | [diff] [blame] | 2606 |       return; | 
 | 2607 |  | 
 | 2608 |     S.Diag(Init->getExprLoc(), | 
 | 2609 |            IsPointer ? diag::warn_init_ptr_member_to_parameter_addr | 
 | 2610 |                      : diag::warn_bind_ref_member_to_parameter) | 
 | 2611 |       << Member << Parameter << Init->getSourceRange(); | 
| Chandler Carruth | bf3380a | 2011-09-03 02:21:57 +0000 | [diff] [blame] | 2612 |   } else { | 
 | 2613 |     // Other initializers are fine. | 
 | 2614 |     return; | 
| Chandler Carruth | 81c6477 | 2011-09-03 01:14:15 +0000 | [diff] [blame] | 2615 |   } | 
| Chandler Carruth | bf3380a | 2011-09-03 02:21:57 +0000 | [diff] [blame] | 2616 |  | 
 | 2617 |   S.Diag(Member->getLocation(), diag::note_ref_or_ptr_member_declared_here) | 
 | 2618 |     << (unsigned)IsPointer; | 
| Chandler Carruth | 81c6477 | 2011-09-03 01:14:15 +0000 | [diff] [blame] | 2619 | } | 
 | 2620 |  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 2621 | MemInitResult | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2622 | Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init, | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2623 |                              SourceLocation IdLoc) { | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2624 |   FieldDecl *DirectMember = dyn_cast<FieldDecl>(Member); | 
 | 2625 |   IndirectFieldDecl *IndirectMember = dyn_cast<IndirectFieldDecl>(Member); | 
 | 2626 |   assert((DirectMember || IndirectMember) && | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 2627 |          "Member must be a FieldDecl or IndirectFieldDecl"); | 
 | 2628 |  | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2629 |   if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer)) | 
| Peter Collingbourne | fef2189 | 2011-10-23 18:59:44 +0000 | [diff] [blame] | 2630 |     return true; | 
 | 2631 |  | 
| Douglas Gregor | 464b2f0 | 2010-11-05 22:21:31 +0000 | [diff] [blame] | 2632 |   if (Member->isInvalidDecl()) | 
 | 2633 |     return true; | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2634 |  | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2635 |   MultiExprArg Args; | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2636 |   if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2637 |     Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs()); | 
| Richard Smith | c83c230 | 2012-12-19 01:39:02 +0000 | [diff] [blame] | 2638 |   } else if (InitListExpr *InitList = dyn_cast<InitListExpr>(Init)) { | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2639 |     Args = MultiExprArg(InitList->getInits(), InitList->getNumInits()); | 
| Richard Smith | c83c230 | 2012-12-19 01:39:02 +0000 | [diff] [blame] | 2640 |   } else { | 
 | 2641 |     // Template instantiation doesn't reconstruct ParenListExprs for us. | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2642 |     Args = Init; | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2643 |   } | 
| Daniel Jasper | f8cc02e | 2012-06-06 08:32:04 +0000 | [diff] [blame] | 2644 |  | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2645 |   SourceRange InitRange = Init->getSourceRange(); | 
| Eli Friedman | 59c0437 | 2009-07-29 19:44:27 +0000 | [diff] [blame] | 2646 |  | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2647 |   if (Member->getType()->isDependentType() || Init->isTypeDependent()) { | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2648 |     // Can't check initialization for a member of dependent type or when | 
 | 2649 |     // any of the arguments are type-dependent expressions. | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2650 |     DiscardCleanupsInEvaluationContext(); | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2651 |   } else { | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2652 |     bool InitList = false; | 
 | 2653 |     if (isa<InitListExpr>(Init)) { | 
 | 2654 |       InitList = true; | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2655 |       Args = Init; | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2656 |     } | 
 | 2657 |  | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2658 |     // Initialize the member. | 
 | 2659 |     InitializedEntity MemberEntity = | 
 | 2660 |       DirectMember ? InitializedEntity::InitializeMember(DirectMember, 0) | 
 | 2661 |                    : InitializedEntity::InitializeMember(IndirectMember, 0); | 
 | 2662 |     InitializationKind Kind = | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2663 |       InitList ? InitializationKind::CreateDirectList(IdLoc) | 
 | 2664 |                : InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(), | 
 | 2665 |                                                   InitRange.getEnd()); | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 2666 |  | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2667 |     InitializationSequence InitSeq(*this, MemberEntity, Kind, Args); | 
 | 2668 |     ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind, Args, 0); | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2669 |     if (MemberInit.isInvalid()) | 
 | 2670 |       return true; | 
 | 2671 |  | 
| Richard Smith | 8a07cd3 | 2013-06-12 20:42:33 +0000 | [diff] [blame] | 2672 |     CheckForDanglingReferenceOrPointer(*this, Member, MemberInit.get(), IdLoc); | 
 | 2673 |  | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 2674 |     // C++11 [class.base.init]p7: | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2675 |     //   The initialization of each base and member constitutes a | 
 | 2676 |     //   full-expression. | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 2677 |     MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin()); | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2678 |     if (MemberInit.isInvalid()) | 
 | 2679 |       return true; | 
 | 2680 |  | 
| Richard Smith | c83c230 | 2012-12-19 01:39:02 +0000 | [diff] [blame] | 2681 |     Init = MemberInit.get(); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2682 |   } | 
 | 2683 |  | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2684 |   if (DirectMember) { | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2685 |     return new (Context) CXXCtorInitializer(Context, DirectMember, IdLoc, | 
 | 2686 |                                             InitRange.getBegin(), Init, | 
 | 2687 |                                             InitRange.getEnd()); | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2688 |   } else { | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2689 |     return new (Context) CXXCtorInitializer(Context, IndirectMember, IdLoc, | 
 | 2690 |                                             InitRange.getBegin(), Init, | 
 | 2691 |                                             InitRange.getEnd()); | 
| Chandler Carruth | 894aed9 | 2010-12-06 09:23:57 +0000 | [diff] [blame] | 2692 |   } | 
| Eli Friedman | 59c0437 | 2009-07-29 19:44:27 +0000 | [diff] [blame] | 2693 | } | 
 | 2694 |  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 2695 | MemInitResult | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2696 | Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init, | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 2697 |                                  CXXRecordDecl *ClassDecl) { | 
| Douglas Gregor | 76852c2 | 2011-11-01 01:16:03 +0000 | [diff] [blame] | 2698 |   SourceLocation NameLoc = TInfo->getTypeLoc().getLocalSourceRange().getBegin(); | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 2699 |   if (!LangOpts.CPlusPlus11) | 
| Douglas Gregor | 76852c2 | 2011-11-01 01:16:03 +0000 | [diff] [blame] | 2700 |     return Diag(NameLoc, diag::err_delegating_ctor) | 
| Sean Hunt | 97fcc49 | 2011-01-08 19:20:43 +0000 | [diff] [blame] | 2701 |       << TInfo->getTypeLoc().getLocalSourceRange(); | 
| Douglas Gregor | 76852c2 | 2011-11-01 01:16:03 +0000 | [diff] [blame] | 2702 |   Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor); | 
| Sebastian Redl | f9c32eb | 2011-03-12 13:53:51 +0000 | [diff] [blame] | 2703 |  | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2704 |   bool InitList = true; | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2705 |   MultiExprArg Args = Init; | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2706 |   if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { | 
 | 2707 |     InitList = false; | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2708 |     Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs()); | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2709 |   } | 
 | 2710 |  | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2711 |   SourceRange InitRange = Init->getSourceRange(); | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 2712 |   // Initialize the object. | 
 | 2713 |   InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation( | 
 | 2714 |                                      QualType(ClassDecl->getTypeForDecl(), 0)); | 
 | 2715 |   InitializationKind Kind = | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2716 |     InitList ? InitializationKind::CreateDirectList(NameLoc) | 
 | 2717 |              : InitializationKind::CreateDirect(NameLoc, InitRange.getBegin(), | 
 | 2718 |                                                 InitRange.getEnd()); | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2719 |   InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args); | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2720 |   ExprResult DelegationInit = InitSeq.Perform(*this, DelegationEntity, Kind, | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2721 |                                               Args, 0); | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 2722 |   if (DelegationInit.isInvalid()) | 
 | 2723 |     return true; | 
 | 2724 |  | 
| Matt Beaumont-Gay | 2eb0ce3 | 2011-11-01 18:10:22 +0000 | [diff] [blame] | 2725 |   assert(cast<CXXConstructExpr>(DelegationInit.get())->getConstructor() && | 
 | 2726 |          "Delegating constructor with no target?"); | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 2727 |  | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 2728 |   // C++11 [class.base.init]p7: | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 2729 |   //   The initialization of each base and member constitutes a | 
 | 2730 |   //   full-expression. | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 2731 |   DelegationInit = ActOnFinishFullExpr(DelegationInit.get(), | 
 | 2732 |                                        InitRange.getBegin()); | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 2733 |   if (DelegationInit.isInvalid()) | 
 | 2734 |     return true; | 
 | 2735 |  | 
| Eli Friedman | d21016f | 2012-05-19 23:35:23 +0000 | [diff] [blame] | 2736 |   // If we are in a dependent context, template instantiation will | 
 | 2737 |   // perform this type-checking again. Just save the arguments that we | 
 | 2738 |   // received in a ParenListExpr. | 
 | 2739 |   // FIXME: This isn't quite ideal, since our ASTs don't capture all | 
 | 2740 |   // of the information that we have about the base | 
 | 2741 |   // initializer. However, deconstructing the ASTs is a dicey process, | 
 | 2742 |   // and this approach is far more likely to get the corner cases right. | 
 | 2743 |   if (CurContext->isDependentContext()) | 
 | 2744 |     DelegationInit = Owned(Init); | 
 | 2745 |  | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2746 |   return new (Context) CXXCtorInitializer(Context, TInfo, InitRange.getBegin(),  | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 2747 |                                           DelegationInit.takeAs<Expr>(), | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2748 |                                           InitRange.getEnd()); | 
| Sean Hunt | 97fcc49 | 2011-01-08 19:20:43 +0000 | [diff] [blame] | 2749 | } | 
 | 2750 |  | 
 | 2751 | MemInitResult | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2752 | Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2753 |                            Expr *Init, CXXRecordDecl *ClassDecl, | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2754 |                            SourceLocation EllipsisLoc) { | 
| Douglas Gregor | 3956b1a | 2010-06-16 16:03:14 +0000 | [diff] [blame] | 2755 |   SourceLocation BaseLoc | 
 | 2756 |     = BaseTInfo->getTypeLoc().getLocalSourceRange().getBegin(); | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2757 |  | 
| Douglas Gregor | 3956b1a | 2010-06-16 16:03:14 +0000 | [diff] [blame] | 2758 |   if (!BaseType->isDependentType() && !BaseType->isRecordType()) | 
 | 2759 |     return Diag(BaseLoc, diag::err_base_init_does_not_name_class) | 
 | 2760 |              << BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange(); | 
 | 2761 |  | 
 | 2762 |   // C++ [class.base.init]p2: | 
 | 2763 |   //   [...] Unless the mem-initializer-id names a nonstatic data | 
| Nick Lewycky | 7663f39 | 2010-11-20 01:29:55 +0000 | [diff] [blame] | 2764 |   //   member of the constructor's class or a direct or virtual base | 
| Douglas Gregor | 3956b1a | 2010-06-16 16:03:14 +0000 | [diff] [blame] | 2765 |   //   of that class, the mem-initializer is ill-formed. A | 
 | 2766 |   //   mem-initializer-list can initialize a base class using any | 
 | 2767 |   //   name that denotes that base class type. | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2768 |   bool Dependent = BaseType->isDependentType() || Init->isTypeDependent(); | 
| Douglas Gregor | 3956b1a | 2010-06-16 16:03:14 +0000 | [diff] [blame] | 2769 |  | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2770 |   SourceRange InitRange = Init->getSourceRange(); | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2771 |   if (EllipsisLoc.isValid()) { | 
 | 2772 |     // This is a pack expansion. | 
 | 2773 |     if (!BaseType->containsUnexpandedParameterPack())  { | 
 | 2774 |       Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2775 |         << SourceRange(BaseLoc, InitRange.getEnd()); | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2776 |  | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2777 |       EllipsisLoc = SourceLocation(); | 
 | 2778 |     } | 
 | 2779 |   } else { | 
 | 2780 |     // Check for any unexpanded parameter packs. | 
 | 2781 |     if (DiagnoseUnexpandedParameterPack(BaseLoc, BaseTInfo, UPPC_Initializer)) | 
 | 2782 |       return true; | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2783 |  | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2784 |     if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer)) | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2785 |       return true; | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2786 |   } | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2787 |  | 
| Douglas Gregor | 3956b1a | 2010-06-16 16:03:14 +0000 | [diff] [blame] | 2788 |   // Check for direct and virtual base classes. | 
 | 2789 |   const CXXBaseSpecifier *DirectBaseSpec = 0; | 
 | 2790 |   const CXXBaseSpecifier *VirtualBaseSpec = 0; | 
 | 2791 |   if (!Dependent) {  | 
| Sean Hunt | 97fcc49 | 2011-01-08 19:20:43 +0000 | [diff] [blame] | 2792 |     if (Context.hasSameUnqualifiedType(QualType(ClassDecl->getTypeForDecl(),0), | 
 | 2793 |                                        BaseType)) | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2794 |       return BuildDelegatingInitializer(BaseTInfo, Init, ClassDecl); | 
| Sean Hunt | 97fcc49 | 2011-01-08 19:20:43 +0000 | [diff] [blame] | 2795 |  | 
| Douglas Gregor | 3956b1a | 2010-06-16 16:03:14 +0000 | [diff] [blame] | 2796 |     FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec,  | 
 | 2797 |                         VirtualBaseSpec); | 
 | 2798 |  | 
 | 2799 |     // C++ [base.class.init]p2: | 
 | 2800 |     // Unless the mem-initializer-id names a nonstatic data member of the | 
 | 2801 |     // constructor's class or a direct or virtual base of that class, the | 
 | 2802 |     // mem-initializer is ill-formed. | 
 | 2803 |     if (!DirectBaseSpec && !VirtualBaseSpec) { | 
 | 2804 |       // If the class has any dependent bases, then it's possible that | 
 | 2805 |       // one of those types will resolve to the same type as | 
 | 2806 |       // BaseType. Therefore, just treat this as a dependent base | 
 | 2807 |       // class initialization.  FIXME: Should we try to check the | 
 | 2808 |       // initialization anyway? It seems odd. | 
 | 2809 |       if (ClassDecl->hasAnyDependentBases()) | 
 | 2810 |         Dependent = true; | 
 | 2811 |       else | 
 | 2812 |         return Diag(BaseLoc, diag::err_not_direct_base_or_virtual) | 
 | 2813 |           << BaseType << Context.getTypeDeclType(ClassDecl) | 
 | 2814 |           << BaseTInfo->getTypeLoc().getLocalSourceRange(); | 
 | 2815 |     } | 
 | 2816 |   } | 
 | 2817 |  | 
 | 2818 |   if (Dependent) { | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2819 |     DiscardCleanupsInEvaluationContext(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2820 |  | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2821 |     return new (Context) CXXCtorInitializer(Context, BaseTInfo, | 
 | 2822 |                                             /*IsVirtual=*/false, | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2823 |                                             InitRange.getBegin(), Init, | 
 | 2824 |                                             InitRange.getEnd(), EllipsisLoc); | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2825 |   } | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2826 |  | 
 | 2827 |   // C++ [base.class.init]p2: | 
 | 2828 |   //   If a mem-initializer-id is ambiguous because it designates both | 
 | 2829 |   //   a direct non-virtual base class and an inherited virtual base | 
 | 2830 |   //   class, the mem-initializer is ill-formed. | 
 | 2831 |   if (DirectBaseSpec && VirtualBaseSpec) | 
 | 2832 |     return Diag(BaseLoc, diag::err_base_init_direct_and_virtual) | 
| Abramo Bagnara | bd054db | 2010-05-20 10:00:11 +0000 | [diff] [blame] | 2833 |       << BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange(); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2834 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 2835 |   const CXXBaseSpecifier *BaseSpec = DirectBaseSpec; | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2836 |   if (!BaseSpec) | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 2837 |     BaseSpec = VirtualBaseSpec; | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2838 |  | 
 | 2839 |   // Initialize the base. | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2840 |   bool InitList = true; | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2841 |   MultiExprArg Args = Init; | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2842 |   if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2843 |     InitList = false; | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2844 |     Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs()); | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2845 |   } | 
| Sebastian Redl | 3a45c0e | 2012-02-12 16:37:36 +0000 | [diff] [blame] | 2846 |  | 
 | 2847 |   InitializedEntity BaseEntity = | 
 | 2848 |     InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec); | 
 | 2849 |   InitializationKind Kind = | 
 | 2850 |     InitList ? InitializationKind::CreateDirectList(BaseLoc) | 
 | 2851 |              : InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(), | 
 | 2852 |                                                 InitRange.getEnd()); | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2853 |   InitializationSequence InitSeq(*this, BaseEntity, Kind, Args); | 
 | 2854 |   ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind, Args, 0); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2855 |   if (BaseInit.isInvalid()) | 
 | 2856 |     return true; | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 2857 |  | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 2858 |   // C++11 [class.base.init]p7: | 
 | 2859 |   //   The initialization of each base and member constitutes a | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2860 |   //   full-expression. | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 2861 |   BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin()); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2862 |   if (BaseInit.isInvalid()) | 
 | 2863 |     return true; | 
 | 2864 |  | 
 | 2865 |   // If we are in a dependent context, template instantiation will | 
 | 2866 |   // perform this type-checking again. Just save the arguments that we | 
 | 2867 |   // received in a ParenListExpr. | 
 | 2868 |   // FIXME: This isn't quite ideal, since our ASTs don't capture all | 
 | 2869 |   // of the information that we have about the base | 
 | 2870 |   // initializer. However, deconstructing the ASTs is a dicey process, | 
 | 2871 |   // and this approach is far more likely to get the corner cases right. | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2872 |   if (CurContext->isDependentContext()) | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2873 |     BaseInit = Owned(Init); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2874 |  | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 2875 |   return new (Context) CXXCtorInitializer(Context, BaseTInfo, | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2876 |                                           BaseSpec->isVirtual(), | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2877 |                                           InitRange.getBegin(), | 
| Sebastian Redl | 6df6548 | 2011-09-24 17:48:25 +0000 | [diff] [blame] | 2878 |                                           BaseInit.takeAs<Expr>(), | 
| Sebastian Redl | 5b9cc5d | 2012-02-11 23:51:47 +0000 | [diff] [blame] | 2879 |                                           InitRange.getEnd(), EllipsisLoc); | 
| Douglas Gregor | 7ad8390 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 2880 | } | 
 | 2881 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 2882 | // Create a static_cast\<T&&>(expr). | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 2883 | static Expr *CastForMoving(Sema &SemaRef, Expr *E, QualType T = QualType()) { | 
 | 2884 |   if (T.isNull()) T = E->getType(); | 
 | 2885 |   QualType TargetType = SemaRef.BuildReferenceType( | 
 | 2886 |       T, /*SpelledAsLValue*/false, SourceLocation(), DeclarationName()); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 2887 |   SourceLocation ExprLoc = E->getLocStart(); | 
 | 2888 |   TypeSourceInfo *TargetLoc = SemaRef.Context.getTrivialTypeSourceInfo( | 
 | 2889 |       TargetType, ExprLoc); | 
 | 2890 |  | 
 | 2891 |   return SemaRef.BuildCXXNamedCast(ExprLoc, tok::kw_static_cast, TargetLoc, E, | 
 | 2892 |                                    SourceRange(ExprLoc, ExprLoc), | 
 | 2893 |                                    E->getSourceRange()).take(); | 
 | 2894 | } | 
 | 2895 |  | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2896 | /// ImplicitInitializerKind - How an implicit base or member initializer should | 
 | 2897 | /// initialize its base or member. | 
 | 2898 | enum ImplicitInitializerKind { | 
 | 2899 |   IIK_Default, | 
 | 2900 |   IIK_Copy, | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 2901 |   IIK_Move, | 
 | 2902 |   IIK_Inherit | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2903 | }; | 
 | 2904 |  | 
| Anders Carlsson | defefd2 | 2010-04-23 02:00:02 +0000 | [diff] [blame] | 2905 | static bool | 
| Anders Carlsson | ddfb75f | 2010-04-23 02:15:47 +0000 | [diff] [blame] | 2906 | BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2907 |                              ImplicitInitializerKind ImplicitInitKind, | 
| Anders Carlsson | 711f34a | 2010-04-21 19:52:01 +0000 | [diff] [blame] | 2908 |                              CXXBaseSpecifier *BaseSpec, | 
| Anders Carlsson | defefd2 | 2010-04-23 02:00:02 +0000 | [diff] [blame] | 2909 |                              bool IsInheritedVirtualBase, | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 2910 |                              CXXCtorInitializer *&CXXBaseInit) { | 
| Anders Carlsson | 84688f2 | 2010-04-20 23:11:20 +0000 | [diff] [blame] | 2911 |   InitializedEntity InitEntity | 
| Anders Carlsson | 711f34a | 2010-04-21 19:52:01 +0000 | [diff] [blame] | 2912 |     = InitializedEntity::InitializeBase(SemaRef.Context, BaseSpec, | 
 | 2913 |                                         IsInheritedVirtualBase); | 
| Anders Carlsson | 84688f2 | 2010-04-20 23:11:20 +0000 | [diff] [blame] | 2914 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 2915 |   ExprResult BaseInit; | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2916 |    | 
 | 2917 |   switch (ImplicitInitKind) { | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 2918 |   case IIK_Inherit: { | 
 | 2919 |     const CXXRecordDecl *Inherited = | 
 | 2920 |         Constructor->getInheritedConstructor()->getParent(); | 
 | 2921 |     const CXXRecordDecl *Base = BaseSpec->getType()->getAsCXXRecordDecl(); | 
 | 2922 |     if (Base && Inherited->getCanonicalDecl() == Base->getCanonicalDecl()) { | 
 | 2923 |       // C++11 [class.inhctor]p8: | 
 | 2924 |       //   Each expression in the expression-list is of the form | 
 | 2925 |       //   static_cast<T&&>(p), where p is the name of the corresponding | 
 | 2926 |       //   constructor parameter and T is the declared type of p. | 
 | 2927 |       SmallVector<Expr*, 16> Args; | 
 | 2928 |       for (unsigned I = 0, E = Constructor->getNumParams(); I != E; ++I) { | 
 | 2929 |         ParmVarDecl *PD = Constructor->getParamDecl(I); | 
 | 2930 |         ExprResult ArgExpr = | 
 | 2931 |             SemaRef.BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(), | 
 | 2932 |                                      VK_LValue, SourceLocation()); | 
 | 2933 |         if (ArgExpr.isInvalid()) | 
 | 2934 |           return true; | 
 | 2935 |         Args.push_back(CastForMoving(SemaRef, ArgExpr.take(), PD->getType())); | 
 | 2936 |       } | 
 | 2937 |  | 
 | 2938 |       InitializationKind InitKind = InitializationKind::CreateDirect( | 
 | 2939 |           Constructor->getLocation(), SourceLocation(), SourceLocation()); | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2940 |       InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, Args); | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 2941 |       BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, Args); | 
 | 2942 |       break; | 
 | 2943 |     } | 
 | 2944 |   } | 
 | 2945 |   // Fall through. | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2946 |   case IIK_Default: { | 
 | 2947 |     InitializationKind InitKind | 
 | 2948 |       = InitializationKind::CreateDefault(Constructor->getLocation()); | 
| Dmitri Gribenko | 62ed889 | 2013-05-05 20:40:26 +0000 | [diff] [blame] | 2949 |     InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, None); | 
 | 2950 |     BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, None); | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2951 |     break; | 
 | 2952 |   } | 
| Anders Carlsson | 84688f2 | 2010-04-20 23:11:20 +0000 | [diff] [blame] | 2953 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 2954 |   case IIK_Move: | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2955 |   case IIK_Copy: { | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 2956 |     bool Moving = ImplicitInitKind == IIK_Move; | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2957 |     ParmVarDecl *Param = Constructor->getParamDecl(0); | 
 | 2958 |     QualType ParamType = Param->getType().getNonReferenceType(); | 
| Eli Friedman | cf7c14c | 2012-01-16 21:00:51 +0000 | [diff] [blame] | 2959 |  | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2960 |     Expr *CopyCtorArg =  | 
| Abramo Bagnara | e4b9276 | 2012-01-27 09:46:47 +0000 | [diff] [blame] | 2961 |       DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), | 
| John McCall | f4b88a4 | 2012-03-10 09:33:50 +0000 | [diff] [blame] | 2962 |                           SourceLocation(), Param, false, | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 2963 |                           Constructor->getLocation(), ParamType, | 
 | 2964 |                           VK_LValue, 0); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 2965 |  | 
| Eli Friedman | 5f2987c | 2012-02-02 03:46:19 +0000 | [diff] [blame] | 2966 |     SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(CopyCtorArg)); | 
 | 2967 |  | 
| Anders Carlsson | c795750 | 2010-04-24 22:02:54 +0000 | [diff] [blame] | 2968 |     // Cast to the base class to avoid ambiguities. | 
| Anders Carlsson | 59b7f15 | 2010-05-01 16:39:01 +0000 | [diff] [blame] | 2969 |     QualType ArgTy =  | 
 | 2970 |       SemaRef.Context.getQualifiedType(BaseSpec->getType().getUnqualifiedType(),  | 
 | 2971 |                                        ParamType.getQualifiers()); | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 2972 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 2973 |     if (Moving) { | 
 | 2974 |       CopyCtorArg = CastForMoving(SemaRef, CopyCtorArg); | 
 | 2975 |     } | 
 | 2976 |  | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 2977 |     CXXCastPath BasePath; | 
 | 2978 |     BasePath.push_back(BaseSpec); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2979 |     CopyCtorArg = SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy, | 
 | 2980 |                                             CK_UncheckedDerivedToBase, | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 2981 |                                             Moving ? VK_XValue : VK_LValue, | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 2982 |                                             &BasePath).take(); | 
| Anders Carlsson | c795750 | 2010-04-24 22:02:54 +0000 | [diff] [blame] | 2983 |  | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2984 |     InitializationKind InitKind | 
 | 2985 |       = InitializationKind::CreateDirect(Constructor->getLocation(), | 
 | 2986 |                                          SourceLocation(), SourceLocation()); | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 2987 |     InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, CopyCtorArg); | 
 | 2988 |     BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, CopyCtorArg); | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2989 |     break; | 
 | 2990 |   } | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 2991 |   } | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 2992 |  | 
| Douglas Gregor | 53c374f | 2010-12-07 00:41:46 +0000 | [diff] [blame] | 2993 |   BaseInit = SemaRef.MaybeCreateExprWithCleanups(BaseInit); | 
| Anders Carlsson | 84688f2 | 2010-04-20 23:11:20 +0000 | [diff] [blame] | 2994 |   if (BaseInit.isInvalid()) | 
| Anders Carlsson | defefd2 | 2010-04-23 02:00:02 +0000 | [diff] [blame] | 2995 |     return true; | 
| Anders Carlsson | 84688f2 | 2010-04-20 23:11:20 +0000 | [diff] [blame] | 2996 |          | 
| Anders Carlsson | defefd2 | 2010-04-23 02:00:02 +0000 | [diff] [blame] | 2997 |   CXXBaseInit = | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 2998 |     new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, | 
| Anders Carlsson | 84688f2 | 2010-04-20 23:11:20 +0000 | [diff] [blame] | 2999 |                SemaRef.Context.getTrivialTypeSourceInfo(BaseSpec->getType(),  | 
 | 3000 |                                                         SourceLocation()), | 
 | 3001 |                                              BaseSpec->isVirtual(), | 
 | 3002 |                                              SourceLocation(), | 
 | 3003 |                                              BaseInit.takeAs<Expr>(), | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 3004 |                                              SourceLocation(), | 
| Anders Carlsson | 84688f2 | 2010-04-20 23:11:20 +0000 | [diff] [blame] | 3005 |                                              SourceLocation()); | 
 | 3006 |  | 
| Anders Carlsson | defefd2 | 2010-04-23 02:00:02 +0000 | [diff] [blame] | 3007 |   return false; | 
| Anders Carlsson | 84688f2 | 2010-04-20 23:11:20 +0000 | [diff] [blame] | 3008 | } | 
 | 3009 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3010 | static bool RefersToRValueRef(Expr *MemRef) { | 
 | 3011 |   ValueDecl *Referenced = cast<MemberExpr>(MemRef)->getMemberDecl(); | 
 | 3012 |   return Referenced->getType()->isRValueReferenceType(); | 
 | 3013 | } | 
 | 3014 |  | 
| Anders Carlsson | ddfb75f | 2010-04-23 02:15:47 +0000 | [diff] [blame] | 3015 | static bool | 
 | 3016 | BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 3017 |                                ImplicitInitializerKind ImplicitInitKind, | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3018 |                                FieldDecl *Field, IndirectFieldDecl *Indirect, | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3019 |                                CXXCtorInitializer *&CXXMemberInit) { | 
| Douglas Gregor | 72a43bb | 2010-05-20 22:12:02 +0000 | [diff] [blame] | 3020 |   if (Field->isInvalidDecl()) | 
 | 3021 |     return true; | 
 | 3022 |  | 
| Chandler Carruth | f186b54 | 2010-06-29 23:50:44 +0000 | [diff] [blame] | 3023 |   SourceLocation Loc = Constructor->getLocation(); | 
 | 3024 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3025 |   if (ImplicitInitKind == IIK_Copy || ImplicitInitKind == IIK_Move) { | 
 | 3026 |     bool Moving = ImplicitInitKind == IIK_Move; | 
| Anders Carlsson | f6513ed | 2010-04-23 16:04:08 +0000 | [diff] [blame] | 3027 |     ParmVarDecl *Param = Constructor->getParamDecl(0); | 
 | 3028 |     QualType ParamType = Param->getType().getNonReferenceType(); | 
| John McCall | b77115d | 2011-06-17 00:18:42 +0000 | [diff] [blame] | 3029 |  | 
 | 3030 |     // Suppress copying zero-width bitfields. | 
| Richard Smith | a6b8b2c | 2011-10-10 18:28:20 +0000 | [diff] [blame] | 3031 |     if (Field->isBitField() && Field->getBitWidthValue(SemaRef.Context) == 0) | 
 | 3032 |       return false; | 
| Douglas Gregor | ddb2147 | 2011-11-02 23:04:16 +0000 | [diff] [blame] | 3033 |          | 
| Anders Carlsson | f6513ed | 2010-04-23 16:04:08 +0000 | [diff] [blame] | 3034 |     Expr *MemberExprBase =  | 
| Abramo Bagnara | e4b9276 | 2012-01-27 09:46:47 +0000 | [diff] [blame] | 3035 |       DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), | 
| John McCall | f4b88a4 | 2012-03-10 09:33:50 +0000 | [diff] [blame] | 3036 |                           SourceLocation(), Param, false, | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3037 |                           Loc, ParamType, VK_LValue, 0); | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3038 |  | 
| Eli Friedman | 5f2987c | 2012-02-02 03:46:19 +0000 | [diff] [blame] | 3039 |     SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(MemberExprBase)); | 
 | 3040 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3041 |     if (Moving) { | 
 | 3042 |       MemberExprBase = CastForMoving(SemaRef, MemberExprBase); | 
 | 3043 |     } | 
 | 3044 |  | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3045 |     // Build a reference to this field within the parameter. | 
 | 3046 |     CXXScopeSpec SS; | 
 | 3047 |     LookupResult MemberLookup(SemaRef, Field->getDeclName(), Loc, | 
 | 3048 |                               Sema::LookupMemberName); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3049 |     MemberLookup.addDecl(Indirect ? cast<ValueDecl>(Indirect) | 
 | 3050 |                                   : cast<ValueDecl>(Field), AS_public); | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3051 |     MemberLookup.resolveKind(); | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 3052 |     ExprResult CtorArg  | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 3053 |       = SemaRef.BuildMemberReferenceExpr(MemberExprBase, | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3054 |                                          ParamType, Loc, | 
 | 3055 |                                          /*IsArrow=*/false, | 
 | 3056 |                                          SS, | 
| Abramo Bagnara | e4b9276 | 2012-01-27 09:46:47 +0000 | [diff] [blame] | 3057 |                                          /*TemplateKWLoc=*/SourceLocation(), | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3058 |                                          /*FirstQualifierInScope=*/0, | 
 | 3059 |                                          MemberLookup, | 
 | 3060 |                                          /*TemplateArgs=*/0);     | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 3061 |     if (CtorArg.isInvalid()) | 
| Anders Carlsson | f6513ed | 2010-04-23 16:04:08 +0000 | [diff] [blame] | 3062 |       return true; | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3063 |  | 
 | 3064 |     // C++11 [class.copy]p15: | 
 | 3065 |     //   - if a member m has rvalue reference type T&&, it is direct-initialized | 
 | 3066 |     //     with static_cast<T&&>(x.m); | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 3067 |     if (RefersToRValueRef(CtorArg.get())) { | 
 | 3068 |       CtorArg = CastForMoving(SemaRef, CtorArg.take()); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3069 |     } | 
 | 3070 |  | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3071 |     // When the field we are copying is an array, create index variables for  | 
 | 3072 |     // each dimension of the array. We use these index variables to subscript | 
 | 3073 |     // the source array, and other clients (e.g., CodeGen) will perform the | 
 | 3074 |     // necessary iteration with these index variables. | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 3075 |     SmallVector<VarDecl *, 4> IndexVariables; | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3076 |     QualType BaseType = Field->getType(); | 
 | 3077 |     QualType SizeType = SemaRef.Context.getSizeType(); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3078 |     bool InitializingArray = false; | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3079 |     while (const ConstantArrayType *Array | 
 | 3080 |                           = SemaRef.Context.getAsConstantArrayType(BaseType)) { | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3081 |       InitializingArray = true; | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3082 |       // Create the iteration variable for this array index. | 
 | 3083 |       IdentifierInfo *IterationVarName = 0; | 
 | 3084 |       { | 
| Dylan Noblesmith | f7ccbad | 2012-02-05 02:13:05 +0000 | [diff] [blame] | 3085 |         SmallString<8> Str; | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3086 |         llvm::raw_svector_ostream OS(Str); | 
 | 3087 |         OS << "__i" << IndexVariables.size(); | 
 | 3088 |         IterationVarName = &SemaRef.Context.Idents.get(OS.str()); | 
 | 3089 |       } | 
 | 3090 |       VarDecl *IterationVar | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 3091 |         = VarDecl::Create(SemaRef.Context, SemaRef.CurContext, Loc, Loc, | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3092 |                           IterationVarName, SizeType, | 
 | 3093 |                         SemaRef.Context.getTrivialTypeSourceInfo(SizeType, Loc), | 
| Rafael Espindola | d2615cc | 2013-04-03 19:27:57 +0000 | [diff] [blame] | 3094 |                           SC_None); | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3095 |       IndexVariables.push_back(IterationVar); | 
 | 3096 |        | 
 | 3097 |       // Create a reference to the iteration variable. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 3098 |       ExprResult IterationVarRef | 
| Eli Friedman | 8c38206 | 2012-01-23 02:35:22 +0000 | [diff] [blame] | 3099 |         = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc); | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3100 |       assert(!IterationVarRef.isInvalid() && | 
 | 3101 |              "Reference to invented variable cannot fail!"); | 
| Eli Friedman | 8c38206 | 2012-01-23 02:35:22 +0000 | [diff] [blame] | 3102 |       IterationVarRef = SemaRef.DefaultLvalueConversion(IterationVarRef.take()); | 
 | 3103 |       assert(!IterationVarRef.isInvalid() && | 
 | 3104 |              "Conversion of invented variable cannot fail!"); | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 3105 |  | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3106 |       // Subscript the array with this iteration variable. | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 3107 |       CtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CtorArg.take(), Loc, | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 3108 |                                                         IterationVarRef.take(), | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 3109 |                                                         Loc); | 
 | 3110 |       if (CtorArg.isInvalid()) | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3111 |         return true; | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3112 |  | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3113 |       BaseType = Array->getElementType(); | 
 | 3114 |     } | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3115 |  | 
 | 3116 |     // The array subscript expression is an lvalue, which is wrong for moving. | 
 | 3117 |     if (Moving && InitializingArray) | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 3118 |       CtorArg = CastForMoving(SemaRef, CtorArg.take()); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3119 |  | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3120 |     // Construct the entity that we will be initializing. For an array, this | 
 | 3121 |     // will be first element in the array, which may require several levels | 
 | 3122 |     // of array-subscript entities.  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 3123 |     SmallVector<InitializedEntity, 4> Entities; | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3124 |     Entities.reserve(1 + IndexVariables.size()); | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3125 |     if (Indirect) | 
 | 3126 |       Entities.push_back(InitializedEntity::InitializeMember(Indirect)); | 
 | 3127 |     else | 
 | 3128 |       Entities.push_back(InitializedEntity::InitializeMember(Field)); | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3129 |     for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I) | 
 | 3130 |       Entities.push_back(InitializedEntity::InitializeElement(SemaRef.Context, | 
 | 3131 |                                                               0, | 
 | 3132 |                                                               Entities.back())); | 
 | 3133 |      | 
 | 3134 |     // Direct-initialize to use the copy constructor. | 
 | 3135 |     InitializationKind InitKind = | 
 | 3136 |       InitializationKind::CreateDirect(Loc, SourceLocation(), SourceLocation()); | 
 | 3137 |      | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 3138 |     Expr *CtorArgE = CtorArg.takeAs<Expr>(); | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 3139 |     InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind, CtorArgE); | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3140 |      | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 3141 |     ExprResult MemberInit | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3142 |       = InitSeq.Perform(SemaRef, Entities.back(), InitKind,  | 
| Sebastian Redl | 74e611a | 2011-09-04 18:14:28 +0000 | [diff] [blame] | 3143 |                         MultiExprArg(&CtorArgE, 1)); | 
| Douglas Gregor | 53c374f | 2010-12-07 00:41:46 +0000 | [diff] [blame] | 3144 |     MemberInit = SemaRef.MaybeCreateExprWithCleanups(MemberInit); | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 3145 |     if (MemberInit.isInvalid()) | 
 | 3146 |       return true; | 
 | 3147 |  | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3148 |     if (Indirect) { | 
 | 3149 |       assert(IndexVariables.size() == 0 &&  | 
 | 3150 |              "Indirect field improperly initialized"); | 
 | 3151 |       CXXMemberInit | 
 | 3152 |         = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect,  | 
 | 3153 |                                                    Loc, Loc,  | 
 | 3154 |                                                    MemberInit.takeAs<Expr>(),  | 
 | 3155 |                                                    Loc); | 
 | 3156 |     } else | 
 | 3157 |       CXXMemberInit = CXXCtorInitializer::Create(SemaRef.Context, Field, Loc,  | 
 | 3158 |                                                  Loc, MemberInit.takeAs<Expr>(),  | 
 | 3159 |                                                  Loc, | 
 | 3160 |                                                  IndexVariables.data(), | 
 | 3161 |                                                  IndexVariables.size()); | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 3162 |     return false; | 
 | 3163 |   } | 
 | 3164 |  | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 3165 |   assert((ImplicitInitKind == IIK_Default || ImplicitInitKind == IIK_Inherit) && | 
 | 3166 |          "Unhandled implicit init kind!"); | 
| Anders Carlsson | f6513ed | 2010-04-23 16:04:08 +0000 | [diff] [blame] | 3167 |  | 
| Anders Carlsson | ddfb75f | 2010-04-23 02:15:47 +0000 | [diff] [blame] | 3168 |   QualType FieldBaseElementType =  | 
 | 3169 |     SemaRef.Context.getBaseElementType(Field->getType()); | 
 | 3170 |    | 
| Anders Carlsson | ddfb75f | 2010-04-23 02:15:47 +0000 | [diff] [blame] | 3171 |   if (FieldBaseElementType->isRecordType()) { | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3172 |     InitializedEntity InitEntity  | 
 | 3173 |       = Indirect? InitializedEntity::InitializeMember(Indirect) | 
 | 3174 |                 : InitializedEntity::InitializeMember(Field); | 
| Anders Carlsson | f6513ed | 2010-04-23 16:04:08 +0000 | [diff] [blame] | 3175 |     InitializationKind InitKind =  | 
| Chandler Carruth | f186b54 | 2010-06-29 23:50:44 +0000 | [diff] [blame] | 3176 |       InitializationKind::CreateDefault(Loc); | 
| Dmitri Gribenko | 62ed889 | 2013-05-05 20:40:26 +0000 | [diff] [blame] | 3177 |  | 
 | 3178 |     InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, None); | 
 | 3179 |     ExprResult MemberInit = | 
 | 3180 |       InitSeq.Perform(SemaRef, InitEntity, InitKind, None); | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 3181 |  | 
| Douglas Gregor | 53c374f | 2010-12-07 00:41:46 +0000 | [diff] [blame] | 3182 |     MemberInit = SemaRef.MaybeCreateExprWithCleanups(MemberInit); | 
| Anders Carlsson | ddfb75f | 2010-04-23 02:15:47 +0000 | [diff] [blame] | 3183 |     if (MemberInit.isInvalid()) | 
 | 3184 |       return true; | 
 | 3185 |      | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3186 |     if (Indirect) | 
 | 3187 |       CXXMemberInit = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, | 
 | 3188 |                                                                Indirect, Loc,  | 
 | 3189 |                                                                Loc, | 
 | 3190 |                                                                MemberInit.get(), | 
 | 3191 |                                                                Loc); | 
 | 3192 |     else | 
 | 3193 |       CXXMemberInit = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, | 
 | 3194 |                                                                Field, Loc, Loc, | 
 | 3195 |                                                                MemberInit.get(), | 
 | 3196 |                                                                Loc); | 
| Anders Carlsson | ddfb75f | 2010-04-23 02:15:47 +0000 | [diff] [blame] | 3197 |     return false; | 
 | 3198 |   } | 
| Anders Carlsson | 114a297 | 2010-04-23 03:07:47 +0000 | [diff] [blame] | 3199 |  | 
| Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 3200 |   if (!Field->getParent()->isUnion()) { | 
 | 3201 |     if (FieldBaseElementType->isReferenceType()) { | 
 | 3202 |       SemaRef.Diag(Constructor->getLocation(),  | 
 | 3203 |                    diag::err_uninitialized_member_in_ctor) | 
 | 3204 |       << (int)Constructor->isImplicit()  | 
 | 3205 |       << SemaRef.Context.getTagDeclType(Constructor->getParent()) | 
 | 3206 |       << 0 << Field->getDeclName(); | 
 | 3207 |       SemaRef.Diag(Field->getLocation(), diag::note_declared_at); | 
 | 3208 |       return true; | 
 | 3209 |     } | 
| Anders Carlsson | 114a297 | 2010-04-23 03:07:47 +0000 | [diff] [blame] | 3210 |  | 
| Sean Hunt | 1f2f384 | 2011-05-17 00:19:05 +0000 | [diff] [blame] | 3211 |     if (FieldBaseElementType.isConstQualified()) { | 
 | 3212 |       SemaRef.Diag(Constructor->getLocation(),  | 
 | 3213 |                    diag::err_uninitialized_member_in_ctor) | 
 | 3214 |       << (int)Constructor->isImplicit()  | 
 | 3215 |       << SemaRef.Context.getTagDeclType(Constructor->getParent()) | 
 | 3216 |       << 1 << Field->getDeclName(); | 
 | 3217 |       SemaRef.Diag(Field->getLocation(), diag::note_declared_at); | 
 | 3218 |       return true; | 
 | 3219 |     } | 
| Anders Carlsson | 114a297 | 2010-04-23 03:07:47 +0000 | [diff] [blame] | 3220 |   } | 
| Anders Carlsson | ddfb75f | 2010-04-23 02:15:47 +0000 | [diff] [blame] | 3221 |    | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 3222 |   if (SemaRef.getLangOpts().ObjCAutoRefCount && | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 3223 |       FieldBaseElementType->isObjCRetainableType() && | 
 | 3224 |       FieldBaseElementType.getObjCLifetime() != Qualifiers::OCL_None && | 
 | 3225 |       FieldBaseElementType.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) { | 
| Douglas Gregor | 3fe52ff | 2012-07-23 04:23:39 +0000 | [diff] [blame] | 3226 |     // ARC: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 3227 |     //   Default-initialize Objective-C pointers to NULL. | 
 | 3228 |     CXXMemberInit | 
 | 3229 |       = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Field,  | 
 | 3230 |                                                  Loc, Loc,  | 
 | 3231 |                  new (SemaRef.Context) ImplicitValueInitExpr(Field->getType()),  | 
 | 3232 |                                                  Loc); | 
 | 3233 |     return false; | 
 | 3234 |   } | 
 | 3235 |        | 
| Anders Carlsson | ddfb75f | 2010-04-23 02:15:47 +0000 | [diff] [blame] | 3236 |   // Nothing to initialize. | 
 | 3237 |   CXXMemberInit = 0; | 
 | 3238 |   return false; | 
 | 3239 | } | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3240 |  | 
 | 3241 | namespace { | 
 | 3242 | struct BaseAndFieldInfo { | 
 | 3243 |   Sema &S; | 
 | 3244 |   CXXConstructorDecl *Ctor; | 
 | 3245 |   bool AnyErrorsInInits; | 
 | 3246 |   ImplicitInitializerKind IIK; | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3247 |   llvm::DenseMap<const void *, CXXCtorInitializer*> AllBaseFields; | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 3248 |   SmallVector<CXXCtorInitializer*, 8> AllToInit; | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3249 |  | 
 | 3250 |   BaseAndFieldInfo(Sema &S, CXXConstructorDecl *Ctor, bool ErrorsInInits) | 
 | 3251 |     : S(S), Ctor(Ctor), AnyErrorsInInits(ErrorsInInits) { | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3252 |     bool Generated = Ctor->isImplicit() || Ctor->isDefaulted(); | 
 | 3253 |     if (Generated && Ctor->isCopyConstructor()) | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3254 |       IIK = IIK_Copy; | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3255 |     else if (Generated && Ctor->isMoveConstructor()) | 
 | 3256 |       IIK = IIK_Move; | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 3257 |     else if (Ctor->getInheritedConstructor()) | 
 | 3258 |       IIK = IIK_Inherit; | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3259 |     else | 
 | 3260 |       IIK = IIK_Default; | 
 | 3261 |   } | 
| Douglas Gregor | f485388 | 2011-11-28 20:03:15 +0000 | [diff] [blame] | 3262 |    | 
 | 3263 |   bool isImplicitCopyOrMove() const { | 
 | 3264 |     switch (IIK) { | 
 | 3265 |     case IIK_Copy: | 
 | 3266 |     case IIK_Move: | 
 | 3267 |       return true; | 
 | 3268 |        | 
 | 3269 |     case IIK_Default: | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 3270 |     case IIK_Inherit: | 
| Douglas Gregor | f485388 | 2011-11-28 20:03:15 +0000 | [diff] [blame] | 3271 |       return false; | 
 | 3272 |     } | 
| David Blaikie | 3026348 | 2012-01-20 21:50:17 +0000 | [diff] [blame] | 3273 |  | 
 | 3274 |     llvm_unreachable("Invalid ImplicitInitializerKind!"); | 
| Douglas Gregor | f485388 | 2011-11-28 20:03:15 +0000 | [diff] [blame] | 3275 |   } | 
| Richard Smith | 0b8220a | 2012-08-07 21:30:42 +0000 | [diff] [blame] | 3276 |  | 
 | 3277 |   bool addFieldInitializer(CXXCtorInitializer *Init) { | 
 | 3278 |     AllToInit.push_back(Init); | 
 | 3279 |  | 
 | 3280 |     // Check whether this initializer makes the field "used". | 
| Richard Smith | c3bf52c | 2013-04-20 22:23:05 +0000 | [diff] [blame] | 3281 |     if (Init->getInit()->HasSideEffects(S.Context)) | 
| Richard Smith | 0b8220a | 2012-08-07 21:30:42 +0000 | [diff] [blame] | 3282 |       S.UnusedPrivateFields.remove(Init->getAnyMember()); | 
 | 3283 |  | 
 | 3284 |     return false; | 
 | 3285 |   } | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3286 | }; | 
 | 3287 | } | 
 | 3288 |  | 
| Richard Smith | a495066 | 2011-09-19 13:34:43 +0000 | [diff] [blame] | 3289 | /// \brief Determine whether the given indirect field declaration is somewhere | 
 | 3290 | /// within an anonymous union. | 
 | 3291 | static bool isWithinAnonymousUnion(IndirectFieldDecl *F) { | 
 | 3292 |   for (IndirectFieldDecl::chain_iterator C = F->chain_begin(),  | 
 | 3293 |                                       CEnd = F->chain_end(); | 
 | 3294 |        C != CEnd; ++C) | 
 | 3295 |     if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>((*C)->getDeclContext())) | 
 | 3296 |       if (Record->isUnion()) | 
 | 3297 |         return true; | 
 | 3298 |          | 
 | 3299 |   return false; | 
 | 3300 | } | 
 | 3301 |  | 
| Douglas Gregor | ddb2147 | 2011-11-02 23:04:16 +0000 | [diff] [blame] | 3302 | /// \brief Determine whether the given type is an incomplete or zero-lenfgth | 
 | 3303 | /// array type. | 
 | 3304 | static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) { | 
 | 3305 |   if (T->isIncompleteArrayType()) | 
 | 3306 |     return true; | 
 | 3307 |    | 
 | 3308 |   while (const ConstantArrayType *ArrayT = Context.getAsConstantArrayType(T)) { | 
 | 3309 |     if (!ArrayT->getSize()) | 
 | 3310 |       return true; | 
 | 3311 |      | 
 | 3312 |     T = ArrayT->getElementType(); | 
 | 3313 |   } | 
 | 3314 |    | 
 | 3315 |   return false; | 
 | 3316 | } | 
 | 3317 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 3318 | static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info, | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3319 |                                     FieldDecl *Field,  | 
 | 3320 |                                     IndirectFieldDecl *Indirect = 0) { | 
| Eli Friedman | 5fb478b | 2013-06-28 21:07:41 +0000 | [diff] [blame] | 3321 |   if (Field->isInvalidDecl()) | 
 | 3322 |     return false; | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3323 |  | 
| Chandler Carruth | e861c60 | 2010-06-30 02:59:29 +0000 | [diff] [blame] | 3324 |   // Overwhelmingly common case: we have a direct initializer for this field. | 
| Richard Smith | 0b8220a | 2012-08-07 21:30:42 +0000 | [diff] [blame] | 3325 |   if (CXXCtorInitializer *Init = Info.AllBaseFields.lookup(Field)) | 
 | 3326 |     return Info.addFieldInitializer(Init); | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3327 |  | 
| Richard Smith | 0b8220a | 2012-08-07 21:30:42 +0000 | [diff] [blame] | 3328 |   // C++11 [class.base.init]p8: if the entity is a non-static data member that | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 3329 |   // has a brace-or-equal-initializer, the entity is initialized as specified | 
 | 3330 |   // in [dcl.init]. | 
| Douglas Gregor | f485388 | 2011-11-28 20:03:15 +0000 | [diff] [blame] | 3331 |   if (Field->hasInClassInitializer() && !Info.isImplicitCopyOrMove()) { | 
| Richard Smith | c3bf52c | 2013-04-20 22:23:05 +0000 | [diff] [blame] | 3332 |     Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context, | 
 | 3333 |                                            Info.Ctor->getLocation(), Field); | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3334 |     CXXCtorInitializer *Init; | 
 | 3335 |     if (Indirect) | 
 | 3336 |       Init = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect, | 
 | 3337 |                                                       SourceLocation(), | 
| Richard Smith | c3bf52c | 2013-04-20 22:23:05 +0000 | [diff] [blame] | 3338 |                                                       SourceLocation(), DIE, | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3339 |                                                       SourceLocation()); | 
 | 3340 |     else | 
 | 3341 |       Init = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Field, | 
 | 3342 |                                                       SourceLocation(), | 
| Richard Smith | c3bf52c | 2013-04-20 22:23:05 +0000 | [diff] [blame] | 3343 |                                                       SourceLocation(), DIE, | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3344 |                                                       SourceLocation()); | 
| Richard Smith | 0b8220a | 2012-08-07 21:30:42 +0000 | [diff] [blame] | 3345 |     return Info.addFieldInitializer(Init); | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 3346 |   } | 
 | 3347 |  | 
| Richard Smith | c115f63 | 2011-09-18 11:14:50 +0000 | [diff] [blame] | 3348 |   // Don't build an implicit initializer for union members if none was | 
 | 3349 |   // explicitly specified. | 
| Richard Smith | a495066 | 2011-09-19 13:34:43 +0000 | [diff] [blame] | 3350 |   if (Field->getParent()->isUnion() || | 
 | 3351 |       (Indirect && isWithinAnonymousUnion(Indirect))) | 
| Richard Smith | c115f63 | 2011-09-18 11:14:50 +0000 | [diff] [blame] | 3352 |     return false; | 
 | 3353 |  | 
| Douglas Gregor | ddb2147 | 2011-11-02 23:04:16 +0000 | [diff] [blame] | 3354 |   // Don't initialize incomplete or zero-length arrays. | 
 | 3355 |   if (isIncompleteOrZeroLengthArrayType(SemaRef.Context, Field->getType())) | 
 | 3356 |     return false; | 
 | 3357 |  | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3358 |   // Don't try to build an implicit initializer if there were semantic | 
 | 3359 |   // errors in any of the initializers (and therefore we might be | 
 | 3360 |   // missing some that the user actually wrote). | 
| Eli Friedman | 5fb478b | 2013-06-28 21:07:41 +0000 | [diff] [blame] | 3361 |   if (Info.AnyErrorsInInits) | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3362 |     return false; | 
 | 3363 |  | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3364 |   CXXCtorInitializer *Init = 0; | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3365 |   if (BuildImplicitMemberInitializer(Info.S, Info.Ctor, Info.IIK, Field, | 
 | 3366 |                                      Indirect, Init)) | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3367 |     return true; | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3368 |  | 
| Richard Smith | 0b8220a | 2012-08-07 21:30:42 +0000 | [diff] [blame] | 3369 |   if (!Init) | 
 | 3370 |     return false; | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 3371 |  | 
| Richard Smith | 0b8220a | 2012-08-07 21:30:42 +0000 | [diff] [blame] | 3372 |   return Info.addFieldInitializer(Init); | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3373 | } | 
| Sean Hunt | 059ce0d | 2011-05-01 07:04:31 +0000 | [diff] [blame] | 3374 |  | 
 | 3375 | bool | 
 | 3376 | Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor, | 
 | 3377 |                                CXXCtorInitializer *Initializer) { | 
| Sean Hunt | fe57eef | 2011-05-04 05:57:24 +0000 | [diff] [blame] | 3378 |   assert(Initializer->isDelegatingInitializer()); | 
| Sean Hunt | 01aacc0 | 2011-05-03 20:43:02 +0000 | [diff] [blame] | 3379 |   Constructor->setNumCtorInitializers(1); | 
 | 3380 |   CXXCtorInitializer **initializer = | 
 | 3381 |     new (Context) CXXCtorInitializer*[1]; | 
 | 3382 |   memcpy(initializer, &Initializer, sizeof (CXXCtorInitializer*)); | 
 | 3383 |   Constructor->setCtorInitializers(initializer); | 
 | 3384 |  | 
| Sean Hunt | b76af9c | 2011-05-03 23:05:34 +0000 | [diff] [blame] | 3385 |   if (CXXDestructorDecl *Dtor = LookupDestructor(Constructor->getParent())) { | 
| Eli Friedman | 5f2987c | 2012-02-02 03:46:19 +0000 | [diff] [blame] | 3386 |     MarkFunctionReferenced(Initializer->getSourceLocation(), Dtor); | 
| Sean Hunt | b76af9c | 2011-05-03 23:05:34 +0000 | [diff] [blame] | 3387 |     DiagnoseUseOfDecl(Dtor, Initializer->getSourceLocation()); | 
 | 3388 |   } | 
 | 3389 |  | 
| Sean Hunt | c159870 | 2011-05-05 00:05:47 +0000 | [diff] [blame] | 3390 |   DelegatingCtorDecls.push_back(Constructor); | 
| Sean Hunt | fe57eef | 2011-05-04 05:57:24 +0000 | [diff] [blame] | 3391 |  | 
| Sean Hunt | 059ce0d | 2011-05-01 07:04:31 +0000 | [diff] [blame] | 3392 |   return false; | 
 | 3393 | } | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3394 |  | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3395 | bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors, | 
 | 3396 |                                ArrayRef<CXXCtorInitializer *> Initializers) { | 
| Douglas Gregor | d836c0d | 2011-09-22 23:04:35 +0000 | [diff] [blame] | 3397 |   if (Constructor->isDependentContext()) { | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3398 |     // Just store the initializers as written, they will be checked during | 
 | 3399 |     // instantiation. | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3400 |     if (!Initializers.empty()) { | 
 | 3401 |       Constructor->setNumCtorInitializers(Initializers.size()); | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3402 |       CXXCtorInitializer **baseOrMemberInitializers = | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3403 |         new (Context) CXXCtorInitializer*[Initializers.size()]; | 
 | 3404 |       memcpy(baseOrMemberInitializers, Initializers.data(), | 
 | 3405 |              Initializers.size() * sizeof(CXXCtorInitializer*)); | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3406 |       Constructor->setCtorInitializers(baseOrMemberInitializers); | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3407 |     } | 
| Richard Smith | 54b3ba8 | 2012-09-25 00:23:05 +0000 | [diff] [blame] | 3408 |  | 
 | 3409 |     // Let template instantiation know whether we had errors. | 
 | 3410 |     if (AnyErrors) | 
 | 3411 |       Constructor->setInvalidDecl(); | 
 | 3412 |  | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3413 |     return false; | 
 | 3414 |   } | 
 | 3415 |  | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3416 |   BaseAndFieldInfo Info(*this, Constructor, AnyErrors); | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 3417 |  | 
| Fariborz Jahanian | 80545ad | 2009-09-03 19:36:46 +0000 | [diff] [blame] | 3418 |   // We need to build the initializer AST according to order of construction | 
 | 3419 |   // and not what user specified in the Initializers list. | 
| Anders Carlsson | ea356fb | 2010-04-02 05:42:15 +0000 | [diff] [blame] | 3420 |   CXXRecordDecl *ClassDecl = Constructor->getParent()->getDefinition(); | 
| Douglas Gregor | d606848 | 2010-03-26 22:43:07 +0000 | [diff] [blame] | 3421 |   if (!ClassDecl) | 
 | 3422 |     return true; | 
 | 3423 |    | 
| Eli Friedman | 80c30da | 2009-11-09 19:20:36 +0000 | [diff] [blame] | 3424 |   bool HadError = false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3425 |  | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3426 |   for (unsigned i = 0; i < Initializers.size(); i++) { | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3427 |     CXXCtorInitializer *Member = Initializers[i]; | 
| Richard Smith | cbc820a | 2013-07-22 02:56:56 +0000 | [diff] [blame] | 3428 |  | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3429 |     if (Member->isBaseInitializer()) | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3430 |       Info.AllBaseFields[Member->getBaseClass()->getAs<RecordType>()] = Member; | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3431 |     else | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 3432 |       Info.AllBaseFields[Member->getAnyMember()] = Member; | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3433 |   } | 
 | 3434 |  | 
| Anders Carlsson | 711f34a | 2010-04-21 19:52:01 +0000 | [diff] [blame] | 3435 |   // Keep track of the direct virtual bases. | 
 | 3436 |   llvm::SmallPtrSet<CXXBaseSpecifier *, 16> DirectVBases; | 
 | 3437 |   for (CXXRecordDecl::base_class_iterator I = ClassDecl->bases_begin(), | 
 | 3438 |        E = ClassDecl->bases_end(); I != E; ++I) { | 
 | 3439 |     if (I->isVirtual()) | 
 | 3440 |       DirectVBases.insert(I); | 
 | 3441 |   } | 
 | 3442 |  | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3443 |   // Push virtual bases before others. | 
 | 3444 |   for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), | 
 | 3445 |        E = ClassDecl->vbases_end(); VBase != E; ++VBase) { | 
 | 3446 |  | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3447 |     if (CXXCtorInitializer *Value | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3448 |         = Info.AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) { | 
| Richard Smith | cbc820a | 2013-07-22 02:56:56 +0000 | [diff] [blame] | 3449 |       // [class.base.init]p7, per DR257: | 
 | 3450 |       //   A mem-initializer where the mem-initializer-id names a virtual base | 
 | 3451 |       //   class is ignored during execution of a constructor of any class that | 
 | 3452 |       //   is not the most derived class. | 
 | 3453 |       if (ClassDecl->isAbstract()) { | 
 | 3454 |         // FIXME: Provide a fixit to remove the base specifier. This requires | 
 | 3455 |         // tracking the location of the associated comma for a base specifier. | 
 | 3456 |         Diag(Value->getSourceLocation(), diag::warn_abstract_vbase_init_ignored) | 
 | 3457 |           << VBase->getType() << ClassDecl; | 
 | 3458 |         DiagnoseAbstractType(ClassDecl); | 
 | 3459 |       } | 
 | 3460 |  | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3461 |       Info.AllToInit.push_back(Value); | 
| Richard Smith | cbc820a | 2013-07-22 02:56:56 +0000 | [diff] [blame] | 3462 |     } else if (!AnyErrors && !ClassDecl->isAbstract()) { | 
 | 3463 |       // [class.base.init]p8, per DR257: | 
 | 3464 |       //   If a given [...] base class is not named by a mem-initializer-id | 
 | 3465 |       //   [...] and the entity is not a virtual base class of an abstract | 
 | 3466 |       //   class, then [...] the entity is default-initialized. | 
| Anders Carlsson | 711f34a | 2010-04-21 19:52:01 +0000 | [diff] [blame] | 3467 |       bool IsInheritedVirtualBase = !DirectVBases.count(VBase); | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3468 |       CXXCtorInitializer *CXXBaseInit; | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3469 |       if (BuildImplicitBaseInitializer(*this, Constructor, Info.IIK, | 
| Richard Smith | cbc820a | 2013-07-22 02:56:56 +0000 | [diff] [blame] | 3470 |                                        VBase, IsInheritedVirtualBase, | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 3471 |                                        CXXBaseInit)) { | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3472 |         HadError = true; | 
 | 3473 |         continue; | 
 | 3474 |       } | 
| Anders Carlsson | 84688f2 | 2010-04-20 23:11:20 +0000 | [diff] [blame] | 3475 |  | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3476 |       Info.AllToInit.push_back(CXXBaseInit); | 
| Fariborz Jahanian | 80545ad | 2009-09-03 19:36:46 +0000 | [diff] [blame] | 3477 |     } | 
 | 3478 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3479 |  | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3480 |   // Non-virtual bases. | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3481 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), | 
 | 3482 |        E = ClassDecl->bases_end(); Base != E; ++Base) { | 
 | 3483 |     // Virtuals are in the virtual base list and already constructed. | 
 | 3484 |     if (Base->isVirtual()) | 
 | 3485 |       continue; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3486 |  | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3487 |     if (CXXCtorInitializer *Value | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3488 |           = Info.AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) { | 
 | 3489 |       Info.AllToInit.push_back(Value); | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3490 |     } else if (!AnyErrors) { | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3491 |       CXXCtorInitializer *CXXBaseInit; | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3492 |       if (BuildImplicitBaseInitializer(*this, Constructor, Info.IIK, | 
| Anders Carlsson | e5ef740 | 2010-04-23 03:10:23 +0000 | [diff] [blame] | 3493 |                                        Base, /*IsInheritedVirtualBase=*/false, | 
| Anders Carlsson | defefd2 | 2010-04-23 02:00:02 +0000 | [diff] [blame] | 3494 |                                        CXXBaseInit)) { | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3495 |         HadError = true; | 
| Fariborz Jahanian | 80545ad | 2009-09-03 19:36:46 +0000 | [diff] [blame] | 3496 |         continue; | 
| Anders Carlsson | bcc12fd | 2010-04-02 06:26:44 +0000 | [diff] [blame] | 3497 |       } | 
| Fariborz Jahanian | 9d43620 | 2009-09-03 21:32:41 +0000 | [diff] [blame] | 3498 |  | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3499 |       Info.AllToInit.push_back(CXXBaseInit); | 
| Fariborz Jahanian | 80545ad | 2009-09-03 19:36:46 +0000 | [diff] [blame] | 3500 |     } | 
 | 3501 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3502 |  | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3503 |   // Fields. | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3504 |   for (DeclContext::decl_iterator Mem = ClassDecl->decls_begin(), | 
 | 3505 |                                MemEnd = ClassDecl->decls_end(); | 
 | 3506 |        Mem != MemEnd; ++Mem) { | 
 | 3507 |     if (FieldDecl *F = dyn_cast<FieldDecl>(*Mem)) { | 
| Douglas Gregor | d61db33 | 2011-10-10 17:22:13 +0000 | [diff] [blame] | 3508 |       // C++ [class.bit]p2: | 
 | 3509 |       //   A declaration for a bit-field that omits the identifier declares an | 
 | 3510 |       //   unnamed bit-field. Unnamed bit-fields are not members and cannot be | 
 | 3511 |       //   initialized. | 
 | 3512 |       if (F->isUnnamedBitfield()) | 
 | 3513 |         continue; | 
| Douglas Gregor | ddb2147 | 2011-11-02 23:04:16 +0000 | [diff] [blame] | 3514 |              | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 3515 |       // If we're not generating the implicit copy/move constructor, then we'll | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3516 |       // handle anonymous struct/union fields based on their individual | 
 | 3517 |       // indirect fields. | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 3518 |       if (F->isAnonymousStructOrUnion() && !Info.isImplicitCopyOrMove()) | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3519 |         continue; | 
 | 3520 |            | 
 | 3521 |       if (CollectFieldInitializer(*this, Info, F)) | 
 | 3522 |         HadError = true; | 
| Fariborz Jahanian | 4142ceb | 2010-05-26 20:19:07 +0000 | [diff] [blame] | 3523 |       continue; | 
 | 3524 |     } | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3525 |      | 
 | 3526 |     // Beyond this point, we only consider default initialization. | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 3527 |     if (Info.isImplicitCopyOrMove()) | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3528 |       continue; | 
 | 3529 |      | 
 | 3530 |     if (IndirectFieldDecl *F = dyn_cast<IndirectFieldDecl>(*Mem)) { | 
 | 3531 |       if (F->getType()->isIncompleteArrayType()) { | 
 | 3532 |         assert(ClassDecl->hasFlexibleArrayMember() && | 
 | 3533 |                "Incomplete array type is not valid"); | 
 | 3534 |         continue; | 
 | 3535 |       } | 
 | 3536 |        | 
| Douglas Gregor | 4dc41c9 | 2011-08-10 15:22:55 +0000 | [diff] [blame] | 3537 |       // Initialize each field of an anonymous struct individually. | 
 | 3538 |       if (CollectFieldInitializer(*this, Info, F->getAnonField(), F)) | 
 | 3539 |         HadError = true; | 
 | 3540 |        | 
 | 3541 |       continue;         | 
 | 3542 |     } | 
| Fariborz Jahanian | 4142ceb | 2010-05-26 20:19:07 +0000 | [diff] [blame] | 3543 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3544 |  | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3545 |   unsigned NumInitializers = Info.AllToInit.size(); | 
| Fariborz Jahanian | 80545ad | 2009-09-03 19:36:46 +0000 | [diff] [blame] | 3546 |   if (NumInitializers > 0) { | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3547 |     Constructor->setNumCtorInitializers(NumInitializers); | 
 | 3548 |     CXXCtorInitializer **baseOrMemberInitializers = | 
 | 3549 |       new (Context) CXXCtorInitializer*[NumInitializers]; | 
| John McCall | f1860e5 | 2010-05-20 23:23:51 +0000 | [diff] [blame] | 3550 |     memcpy(baseOrMemberInitializers, Info.AllToInit.data(), | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3551 |            NumInitializers * sizeof(CXXCtorInitializer*)); | 
 | 3552 |     Constructor->setCtorInitializers(baseOrMemberInitializers); | 
| Rafael Espindola | 961b167 | 2010-03-13 18:12:56 +0000 | [diff] [blame] | 3553 |  | 
| John McCall | ef027fe | 2010-03-16 21:39:52 +0000 | [diff] [blame] | 3554 |     // Constructors implicitly reference the base and member | 
 | 3555 |     // destructors. | 
 | 3556 |     MarkBaseAndMemberDestructorsReferenced(Constructor->getLocation(), | 
 | 3557 |                                            Constructor->getParent()); | 
| Fariborz Jahanian | 80545ad | 2009-09-03 19:36:46 +0000 | [diff] [blame] | 3558 |   } | 
| Eli Friedman | 80c30da | 2009-11-09 19:20:36 +0000 | [diff] [blame] | 3559 |  | 
 | 3560 |   return HadError; | 
| Fariborz Jahanian | 80545ad | 2009-09-03 19:36:46 +0000 | [diff] [blame] | 3561 | } | 
 | 3562 |  | 
| David Blaikie | ee000bb | 2013-01-17 08:49:22 +0000 | [diff] [blame] | 3563 | static void PopulateKeysForFields(FieldDecl *Field, SmallVectorImpl<const void*> &IdealInits) { | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 3564 |   if (const RecordType *RT = Field->getType()->getAs<RecordType>()) { | 
| David Blaikie | ee000bb | 2013-01-17 08:49:22 +0000 | [diff] [blame] | 3565 |     const RecordDecl *RD = RT->getDecl(); | 
 | 3566 |     if (RD->isAnonymousStructOrUnion()) { | 
 | 3567 |       for (RecordDecl::field_iterator Field = RD->field_begin(), | 
 | 3568 |           E = RD->field_end(); Field != E; ++Field) | 
 | 3569 |         PopulateKeysForFields(*Field, IdealInits); | 
 | 3570 |       return; | 
 | 3571 |     } | 
| Eli Friedman | 6347f42 | 2009-07-21 19:28:10 +0000 | [diff] [blame] | 3572 |   } | 
| David Blaikie | ee000bb | 2013-01-17 08:49:22 +0000 | [diff] [blame] | 3573 |   IdealInits.push_back(Field); | 
| Eli Friedman | 6347f42 | 2009-07-21 19:28:10 +0000 | [diff] [blame] | 3574 | } | 
 | 3575 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 3576 | static const void *GetKeyForBase(ASTContext &Context, QualType BaseType) { | 
 | 3577 |   return Context.getCanonicalType(BaseType).getTypePtr(); | 
| Anders Carlsson | cdc83c7 | 2009-09-01 06:22:14 +0000 | [diff] [blame] | 3578 | } | 
 | 3579 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 3580 | static const void *GetKeyForMember(ASTContext &Context, | 
 | 3581 |                                    CXXCtorInitializer *Member) { | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 3582 |   if (!Member->isAnyMemberInitializer()) | 
| Anders Carlsson | ea356fb | 2010-04-02 05:42:15 +0000 | [diff] [blame] | 3583 |     return GetKeyForBase(Context, QualType(Member->getBaseClass(), 0)); | 
| Anders Carlsson | 8f1a240 | 2010-03-30 15:39:27 +0000 | [diff] [blame] | 3584 |      | 
| David Blaikie | ee000bb | 2013-01-17 08:49:22 +0000 | [diff] [blame] | 3585 |   return Member->getAnyMember(); | 
| Eli Friedman | 6347f42 | 2009-07-21 19:28:10 +0000 | [diff] [blame] | 3586 | } | 
 | 3587 |  | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3588 | static void DiagnoseBaseOrMemInitializerOrder( | 
 | 3589 |     Sema &SemaRef, const CXXConstructorDecl *Constructor, | 
 | 3590 |     ArrayRef<CXXCtorInitializer *> Inits) { | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3591 |   if (Constructor->getDeclContext()->isDependentContext()) | 
| Anders Carlsson | 8d4c5ea | 2009-08-27 05:57:30 +0000 | [diff] [blame] | 3592 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3593 |  | 
| Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 3594 |   // Don't check initializers order unless the warning is enabled at the | 
 | 3595 |   // location of at least one initializer.  | 
 | 3596 |   bool ShouldCheckOrder = false; | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3597 |   for (unsigned InitIndex = 0; InitIndex != Inits.size(); ++InitIndex) { | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3598 |     CXXCtorInitializer *Init = Inits[InitIndex]; | 
| Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 3599 |     if (SemaRef.Diags.getDiagnosticLevel(diag::warn_initializer_out_of_order, | 
 | 3600 |                                          Init->getSourceLocation()) | 
| David Blaikie | d6471f7 | 2011-09-25 23:23:43 +0000 | [diff] [blame] | 3601 |           != DiagnosticsEngine::Ignored) { | 
| Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 3602 |       ShouldCheckOrder = true; | 
 | 3603 |       break; | 
 | 3604 |     } | 
 | 3605 |   } | 
 | 3606 |   if (!ShouldCheckOrder) | 
| Anders Carlsson | 5c36fb2 | 2009-08-27 05:45:01 +0000 | [diff] [blame] | 3607 |     return; | 
| Anders Carlsson | 58cfbde | 2010-04-02 03:37:03 +0000 | [diff] [blame] | 3608 |    | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3609 |   // Build the list of bases and members in the order that they'll | 
 | 3610 |   // actually be initialized.  The explicit initializers should be in | 
 | 3611 |   // this same order but may be missing things. | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 3612 |   SmallVector<const void*, 32> IdealInitKeys; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3613 |  | 
| Anders Carlsson | 071d610 | 2010-04-02 03:38:04 +0000 | [diff] [blame] | 3614 |   const CXXRecordDecl *ClassDecl = Constructor->getParent(); | 
 | 3615 |  | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3616 |   // 1. Virtual bases. | 
| Anders Carlsson | 071d610 | 2010-04-02 03:38:04 +0000 | [diff] [blame] | 3617 |   for (CXXRecordDecl::base_class_const_iterator VBase = | 
| Anders Carlsson | 5c36fb2 | 2009-08-27 05:45:01 +0000 | [diff] [blame] | 3618 |        ClassDecl->vbases_begin(), | 
 | 3619 |        E = ClassDecl->vbases_end(); VBase != E; ++VBase) | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3620 |     IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, VBase->getType())); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3621 |  | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3622 |   // 2. Non-virtual bases. | 
| Anders Carlsson | 071d610 | 2010-04-02 03:38:04 +0000 | [diff] [blame] | 3623 |   for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(), | 
| Anders Carlsson | 5c36fb2 | 2009-08-27 05:45:01 +0000 | [diff] [blame] | 3624 |        E = ClassDecl->bases_end(); Base != E; ++Base) { | 
| Anders Carlsson | 5c36fb2 | 2009-08-27 05:45:01 +0000 | [diff] [blame] | 3625 |     if (Base->isVirtual()) | 
 | 3626 |       continue; | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3627 |     IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, Base->getType())); | 
| Anders Carlsson | 5c36fb2 | 2009-08-27 05:45:01 +0000 | [diff] [blame] | 3628 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3629 |  | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3630 |   // 3. Direct fields. | 
| Anders Carlsson | 5c36fb2 | 2009-08-27 05:45:01 +0000 | [diff] [blame] | 3631 |   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), | 
| Douglas Gregor | d61db33 | 2011-10-10 17:22:13 +0000 | [diff] [blame] | 3632 |        E = ClassDecl->field_end(); Field != E; ++Field) { | 
 | 3633 |     if (Field->isUnnamedBitfield()) | 
 | 3634 |       continue; | 
 | 3635 |      | 
| David Blaikie | ee000bb | 2013-01-17 08:49:22 +0000 | [diff] [blame] | 3636 |     PopulateKeysForFields(*Field, IdealInitKeys); | 
| Douglas Gregor | d61db33 | 2011-10-10 17:22:13 +0000 | [diff] [blame] | 3637 |   } | 
 | 3638 |    | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3639 |   unsigned NumIdealInits = IdealInitKeys.size(); | 
 | 3640 |   unsigned IdealIndex = 0; | 
| Eli Friedman | 6347f42 | 2009-07-21 19:28:10 +0000 | [diff] [blame] | 3641 |  | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3642 |   CXXCtorInitializer *PrevInit = 0; | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3643 |   for (unsigned InitIndex = 0; InitIndex != Inits.size(); ++InitIndex) { | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3644 |     CXXCtorInitializer *Init = Inits[InitIndex]; | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 3645 |     const void *InitKey = GetKeyForMember(SemaRef.Context, Init); | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3646 |  | 
 | 3647 |     // Scan forward to try to find this initializer in the idealized | 
 | 3648 |     // initializers list. | 
 | 3649 |     for (; IdealIndex != NumIdealInits; ++IdealIndex) | 
 | 3650 |       if (InitKey == IdealInitKeys[IdealIndex]) | 
| Anders Carlsson | 5c36fb2 | 2009-08-27 05:45:01 +0000 | [diff] [blame] | 3651 |         break; | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3652 |  | 
 | 3653 |     // If we didn't find this initializer, it must be because we | 
 | 3654 |     // scanned past it on a previous iteration.  That can only | 
 | 3655 |     // happen if we're out of order;  emit a warning. | 
| Douglas Gregor | fe2d379 | 2010-05-20 23:49:34 +0000 | [diff] [blame] | 3656 |     if (IdealIndex == NumIdealInits && PrevInit) { | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3657 |       Sema::SemaDiagnosticBuilder D = | 
 | 3658 |         SemaRef.Diag(PrevInit->getSourceLocation(), | 
 | 3659 |                      diag::warn_initializer_out_of_order); | 
 | 3660 |  | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 3661 |       if (PrevInit->isAnyMemberInitializer()) | 
 | 3662 |         D << 0 << PrevInit->getAnyMember()->getDeclName(); | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3663 |       else | 
| Douglas Gregor | 76852c2 | 2011-11-01 01:16:03 +0000 | [diff] [blame] | 3664 |         D << 1 << PrevInit->getTypeSourceInfo()->getType(); | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3665 |        | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 3666 |       if (Init->isAnyMemberInitializer()) | 
 | 3667 |         D << 0 << Init->getAnyMember()->getDeclName(); | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3668 |       else | 
| Douglas Gregor | 76852c2 | 2011-11-01 01:16:03 +0000 | [diff] [blame] | 3669 |         D << 1 << Init->getTypeSourceInfo()->getType(); | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3670 |  | 
 | 3671 |       // Move back to the initializer's location in the ideal list. | 
 | 3672 |       for (IdealIndex = 0; IdealIndex != NumIdealInits; ++IdealIndex) | 
 | 3673 |         if (InitKey == IdealInitKeys[IdealIndex]) | 
| Anders Carlsson | 5c36fb2 | 2009-08-27 05:45:01 +0000 | [diff] [blame] | 3674 |           break; | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3675 |  | 
 | 3676 |       assert(IdealIndex != NumIdealInits && | 
 | 3677 |              "initializer not found in initializer list"); | 
| Fariborz Jahanian | eb96e12 | 2009-07-09 19:59:47 +0000 | [diff] [blame] | 3678 |     } | 
| John McCall | d6ca8da | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 3679 |  | 
 | 3680 |     PrevInit = Init; | 
| Fariborz Jahanian | eb96e12 | 2009-07-09 19:59:47 +0000 | [diff] [blame] | 3681 |   } | 
| Anders Carlsson | a7b3521 | 2009-03-25 02:58:17 +0000 | [diff] [blame] | 3682 | } | 
 | 3683 |  | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3684 | namespace { | 
 | 3685 | bool CheckRedundantInit(Sema &S, | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3686 |                         CXXCtorInitializer *Init, | 
 | 3687 |                         CXXCtorInitializer *&PrevInit) { | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3688 |   if (!PrevInit) { | 
 | 3689 |     PrevInit = Init; | 
 | 3690 |     return false; | 
 | 3691 |   } | 
 | 3692 |  | 
| Douglas Gregor | dc392c1 | 2013-03-25 23:28:23 +0000 | [diff] [blame] | 3693 |   if (FieldDecl *Field = Init->getAnyMember()) | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3694 |     S.Diag(Init->getSourceLocation(), | 
 | 3695 |            diag::err_multiple_mem_initialization) | 
 | 3696 |       << Field->getDeclName() | 
 | 3697 |       << Init->getSourceRange(); | 
 | 3698 |   else { | 
| John McCall | f4c7371 | 2011-01-19 06:33:43 +0000 | [diff] [blame] | 3699 |     const Type *BaseClass = Init->getBaseClass(); | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3700 |     assert(BaseClass && "neither field nor base"); | 
 | 3701 |     S.Diag(Init->getSourceLocation(), | 
 | 3702 |            diag::err_multiple_base_initialization) | 
 | 3703 |       << QualType(BaseClass, 0) | 
 | 3704 |       << Init->getSourceRange(); | 
 | 3705 |   } | 
 | 3706 |   S.Diag(PrevInit->getSourceLocation(), diag::note_previous_initializer) | 
 | 3707 |     << 0 << PrevInit->getSourceRange(); | 
 | 3708 |  | 
 | 3709 |   return true; | 
 | 3710 | } | 
 | 3711 |  | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3712 | typedef std::pair<NamedDecl *, CXXCtorInitializer *> UnionEntry; | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3713 | typedef llvm::DenseMap<RecordDecl*, UnionEntry> RedundantUnionMap; | 
 | 3714 |  | 
 | 3715 | bool CheckRedundantUnionInit(Sema &S, | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3716 |                              CXXCtorInitializer *Init, | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3717 |                              RedundantUnionMap &Unions) { | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 3718 |   FieldDecl *Field = Init->getAnyMember(); | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3719 |   RecordDecl *Parent = Field->getParent(); | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3720 |   NamedDecl *Child = Field; | 
| David Blaikie | 6fe2965 | 2011-11-17 06:01:57 +0000 | [diff] [blame] | 3721 |  | 
 | 3722 |   while (Parent->isAnonymousStructOrUnion() || Parent->isUnion()) { | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3723 |     if (Parent->isUnion()) { | 
 | 3724 |       UnionEntry &En = Unions[Parent]; | 
 | 3725 |       if (En.first && En.first != Child) { | 
 | 3726 |         S.Diag(Init->getSourceLocation(), | 
 | 3727 |                diag::err_multiple_mem_union_initialization) | 
 | 3728 |           << Field->getDeclName() | 
 | 3729 |           << Init->getSourceRange(); | 
 | 3730 |         S.Diag(En.second->getSourceLocation(), diag::note_previous_initializer) | 
 | 3731 |           << 0 << En.second->getSourceRange(); | 
 | 3732 |         return true; | 
| David Blaikie | 5bbe816 | 2011-11-12 20:54:14 +0000 | [diff] [blame] | 3733 |       }  | 
 | 3734 |       if (!En.first) { | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3735 |         En.first = Child; | 
 | 3736 |         En.second = Init; | 
 | 3737 |       } | 
| David Blaikie | 6fe2965 | 2011-11-17 06:01:57 +0000 | [diff] [blame] | 3738 |       if (!Parent->isAnonymousStructOrUnion()) | 
 | 3739 |         return false; | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3740 |     } | 
 | 3741 |  | 
 | 3742 |     Child = Parent; | 
 | 3743 |     Parent = cast<RecordDecl>(Parent->getDeclContext()); | 
| David Blaikie | 6fe2965 | 2011-11-17 06:01:57 +0000 | [diff] [blame] | 3744 |   } | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3745 |  | 
 | 3746 |   return false; | 
 | 3747 | } | 
 | 3748 | } | 
 | 3749 |  | 
| Richard Trieu | 225e982 | 2013-09-16 21:54:53 +0000 | [diff] [blame] | 3750 | // Diagnose value-uses of fields to initialize themselves, e.g. | 
 | 3751 | //   foo(foo) | 
 | 3752 | // where foo is not also a parameter to the constructor. | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 3753 | // Also diagnose across field uninitialized use such as | 
 | 3754 | //   x(y), y(x) | 
| Richard Trieu | 225e982 | 2013-09-16 21:54:53 +0000 | [diff] [blame] | 3755 | // TODO: implement -Wuninitialized and fold this into that framework. | 
| Richard Trieu | 225e982 | 2013-09-16 21:54:53 +0000 | [diff] [blame] | 3756 | static void DiagnoseUnitializedFields( | 
 | 3757 |     Sema &SemaRef, const CXXConstructorDecl *Constructor) { | 
 | 3758 |  | 
 | 3759 |   if (SemaRef.getDiagnostics().getDiagnosticLevel(diag::warn_field_is_uninit, | 
 | 3760 |                                                   Constructor->getLocation()) | 
 | 3761 |       == DiagnosticsEngine::Ignored) { | 
 | 3762 |     return; | 
 | 3763 |   } | 
 | 3764 |  | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 3765 |   const CXXRecordDecl *RD = Constructor->getParent(); | 
 | 3766 |  | 
 | 3767 |   // Holds fields that are uninitialized. | 
 | 3768 |   llvm::SmallPtrSet<ValueDecl*, 4> UninitializedFields; | 
 | 3769 |  | 
 | 3770 |   for (DeclContext::decl_iterator I = RD->decls_begin(), E = RD->decls_end(); | 
 | 3771 |        I != E; ++I) { | 
 | 3772 |     if (FieldDecl *FD = dyn_cast<FieldDecl>(*I)) { | 
 | 3773 |       UninitializedFields.insert(FD); | 
 | 3774 |     } else if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(*I)) { | 
 | 3775 |       UninitializedFields.insert(IFD->getAnonField()); | 
 | 3776 |     } | 
 | 3777 |   } | 
 | 3778 |  | 
 | 3779 |   // Fields already checked when processing the in class initializers. | 
 | 3780 |   llvm::SmallPtrSet<ValueDecl*, 4> | 
 | 3781 |       InClassUninitializedFields = UninitializedFields; | 
 | 3782 |  | 
 | 3783 |   for (CXXConstructorDecl::init_const_iterator FieldInit = | 
 | 3784 |            Constructor->init_begin(), | 
| Richard Trieu | 225e982 | 2013-09-16 21:54:53 +0000 | [diff] [blame] | 3785 |            FieldInitEnd = Constructor->init_end(); | 
 | 3786 |        FieldInit != FieldInitEnd; ++FieldInit) { | 
 | 3787 |  | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 3788 |     FieldDecl *Field = (*FieldInit)->getAnyMember(); | 
| Richard Trieu | 225e982 | 2013-09-16 21:54:53 +0000 | [diff] [blame] | 3789 |     Expr *InitExpr = (*FieldInit)->getInit(); | 
 | 3790 |  | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 3791 |     if (!Field) { | 
 | 3792 |       CheckInitExprContainsUninitializedFields( | 
 | 3793 |           SemaRef, InitExpr, 0, UninitializedFields, | 
 | 3794 |           false/*WarnOnSelfReference*/); | 
 | 3795 |       continue; | 
| Richard Trieu | 225e982 | 2013-09-16 21:54:53 +0000 | [diff] [blame] | 3796 |     } | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 3797 |  | 
 | 3798 |     if (CXXDefaultInitExpr *Default = dyn_cast<CXXDefaultInitExpr>(InitExpr)) { | 
 | 3799 |       // This field is initialized with an in-class initailzer.  Remove the | 
 | 3800 |       // fields already checked to prevent duplicate warnings. | 
 | 3801 |       llvm::SmallPtrSet<ValueDecl*, 4> DiffSet = UninitializedFields; | 
 | 3802 |       for (llvm::SmallPtrSet<ValueDecl*, 4>::iterator | 
 | 3803 |                I = InClassUninitializedFields.begin(), | 
 | 3804 |                E = InClassUninitializedFields.end(); | 
 | 3805 |            I != E; ++I) { | 
 | 3806 |         DiffSet.erase(*I); | 
 | 3807 |       } | 
 | 3808 |       CheckInitExprContainsUninitializedFields( | 
 | 3809 |             SemaRef, Default->getExpr(), Field, DiffSet, | 
 | 3810 |             DiffSet.count(Field), Constructor); | 
 | 3811 |  | 
 | 3812 |       // Update the unitialized field sets. | 
 | 3813 |       CheckInitExprContainsUninitializedFields( | 
 | 3814 |             SemaRef, Default->getExpr(), 0, UninitializedFields, | 
 | 3815 |             false); | 
 | 3816 |       CheckInitExprContainsUninitializedFields( | 
 | 3817 |             SemaRef, Default->getExpr(), 0, InClassUninitializedFields, | 
 | 3818 |             false); | 
 | 3819 |     } else { | 
 | 3820 |       CheckInitExprContainsUninitializedFields( | 
 | 3821 |           SemaRef, InitExpr, Field, UninitializedFields, | 
 | 3822 |           UninitializedFields.count(Field)); | 
 | 3823 |       if (Expr* InClassInit = Field->getInClassInitializer()) { | 
 | 3824 |         CheckInitExprContainsUninitializedFields( | 
 | 3825 |             SemaRef, InClassInit, 0, InClassUninitializedFields, | 
 | 3826 |             false); | 
 | 3827 |       } | 
 | 3828 |     } | 
 | 3829 |     UninitializedFields.erase(Field); | 
 | 3830 |     InClassUninitializedFields.erase(Field); | 
| Richard Trieu | 225e982 | 2013-09-16 21:54:53 +0000 | [diff] [blame] | 3831 |   } | 
 | 3832 | } | 
 | 3833 |  | 
| Anders Carlsson | 58cfbde | 2010-04-02 03:37:03 +0000 | [diff] [blame] | 3834 | /// ActOnMemInitializers - Handle the member initializers for a constructor. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 3835 | void Sema::ActOnMemInitializers(Decl *ConstructorDecl, | 
| Anders Carlsson | 58cfbde | 2010-04-02 03:37:03 +0000 | [diff] [blame] | 3836 |                                 SourceLocation ColonLoc, | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3837 |                                 ArrayRef<CXXCtorInitializer*> MemInits, | 
| Anders Carlsson | 58cfbde | 2010-04-02 03:37:03 +0000 | [diff] [blame] | 3838 |                                 bool AnyErrors) { | 
 | 3839 |   if (!ConstructorDecl) | 
 | 3840 |     return; | 
 | 3841 |  | 
 | 3842 |   AdjustDeclIfTemplate(ConstructorDecl); | 
 | 3843 |  | 
 | 3844 |   CXXConstructorDecl *Constructor | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 3845 |     = dyn_cast<CXXConstructorDecl>(ConstructorDecl); | 
| Anders Carlsson | 58cfbde | 2010-04-02 03:37:03 +0000 | [diff] [blame] | 3846 |  | 
 | 3847 |   if (!Constructor) { | 
 | 3848 |     Diag(ColonLoc, diag::err_only_constructors_take_base_inits); | 
 | 3849 |     return; | 
 | 3850 |   } | 
 | 3851 |    | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3852 |   // Mapping for the duplicate initializers check. | 
 | 3853 |   // For member initializers, this is keyed with a FieldDecl*. | 
 | 3854 |   // For base initializers, this is keyed with a Type*. | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 3855 |   llvm::DenseMap<const void *, CXXCtorInitializer *> Members; | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3856 |  | 
 | 3857 |   // Mapping for the inconsistent anonymous-union initializers check. | 
 | 3858 |   RedundantUnionMap MemberUnions; | 
 | 3859 |  | 
| Anders Carlsson | ea356fb | 2010-04-02 05:42:15 +0000 | [diff] [blame] | 3860 |   bool HadError = false; | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3861 |   for (unsigned i = 0; i < MemInits.size(); i++) { | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 3862 |     CXXCtorInitializer *Init = MemInits[i]; | 
| Anders Carlsson | 58cfbde | 2010-04-02 03:37:03 +0000 | [diff] [blame] | 3863 |  | 
| Abramo Bagnara | a0af3b4 | 2010-05-26 18:09:23 +0000 | [diff] [blame] | 3864 |     // Set the source order index. | 
 | 3865 |     Init->setSourceOrder(i); | 
 | 3866 |  | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 3867 |     if (Init->isAnyMemberInitializer()) { | 
 | 3868 |       FieldDecl *Field = Init->getAnyMember(); | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3869 |       if (CheckRedundantInit(*this, Init, Members[Field]) || | 
 | 3870 |           CheckRedundantUnionInit(*this, Init, MemberUnions)) | 
 | 3871 |         HadError = true; | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 3872 |     } else if (Init->isBaseInitializer()) { | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 3873 |       const void *Key = | 
 | 3874 |           GetKeyForBase(Context, QualType(Init->getBaseClass(), 0)); | 
| John McCall | 3c3ccdb | 2010-04-10 09:28:51 +0000 | [diff] [blame] | 3875 |       if (CheckRedundantInit(*this, Init, Members[Key])) | 
 | 3876 |         HadError = true; | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 3877 |     } else { | 
 | 3878 |       assert(Init->isDelegatingInitializer()); | 
 | 3879 |       // This must be the only initializer | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3880 |       if (MemInits.size() != 1) { | 
| Richard Smith | a6ddea6 | 2012-09-14 18:21:10 +0000 | [diff] [blame] | 3881 |         Diag(Init->getSourceLocation(), | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 3882 |              diag::err_delegating_initializer_alone) | 
| Richard Smith | a6ddea6 | 2012-09-14 18:21:10 +0000 | [diff] [blame] | 3883 |           << Init->getSourceRange() << MemInits[i ? 0 : 1]->getSourceRange(); | 
| Sean Hunt | 059ce0d | 2011-05-01 07:04:31 +0000 | [diff] [blame] | 3884 |         // We will treat this as being the only initializer. | 
| Sean Hunt | 4171766 | 2011-02-26 19:13:13 +0000 | [diff] [blame] | 3885 |       } | 
| Sean Hunt | fe57eef | 2011-05-04 05:57:24 +0000 | [diff] [blame] | 3886 |       SetDelegatingInitializer(Constructor, MemInits[i]); | 
| Sean Hunt | 059ce0d | 2011-05-01 07:04:31 +0000 | [diff] [blame] | 3887 |       // Return immediately as the initializer is set. | 
 | 3888 |       return; | 
| Anders Carlsson | 58cfbde | 2010-04-02 03:37:03 +0000 | [diff] [blame] | 3889 |     } | 
| Anders Carlsson | 58cfbde | 2010-04-02 03:37:03 +0000 | [diff] [blame] | 3890 |   } | 
 | 3891 |  | 
| Anders Carlsson | ea356fb | 2010-04-02 05:42:15 +0000 | [diff] [blame] | 3892 |   if (HadError) | 
 | 3893 |     return; | 
 | 3894 |  | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3895 |   DiagnoseBaseOrMemInitializerOrder(*this, Constructor, MemInits); | 
| Anders Carlsson | ec3332b | 2010-04-02 03:43:34 +0000 | [diff] [blame] | 3896 |  | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 3897 |   SetCtorInitializers(Constructor, AnyErrors, MemInits); | 
| Richard Trieu | 225e982 | 2013-09-16 21:54:53 +0000 | [diff] [blame] | 3898 |  | 
 | 3899 |   DiagnoseUnitializedFields(*this, Constructor); | 
| Anders Carlsson | 58cfbde | 2010-04-02 03:37:03 +0000 | [diff] [blame] | 3900 | } | 
 | 3901 |  | 
| Fariborz Jahanian | 34374e6 | 2009-09-03 23:18:17 +0000 | [diff] [blame] | 3902 | void | 
| John McCall | ef027fe | 2010-03-16 21:39:52 +0000 | [diff] [blame] | 3903 | Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location, | 
 | 3904 |                                              CXXRecordDecl *ClassDecl) { | 
| Richard Smith | 416f63e | 2011-09-18 12:11:43 +0000 | [diff] [blame] | 3905 |   // Ignore dependent contexts. Also ignore unions, since their members never | 
 | 3906 |   // have destructors implicitly called. | 
 | 3907 |   if (ClassDecl->isDependentContext() || ClassDecl->isUnion()) | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3908 |     return; | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3909 |  | 
 | 3910 |   // FIXME: all the access-control diagnostics are positioned on the | 
 | 3911 |   // field/base declaration.  That's probably good; that said, the | 
 | 3912 |   // user might reasonably want to know why the destructor is being | 
 | 3913 |   // emitted, and we currently don't say. | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3914 |    | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3915 |   // Non-static data members. | 
 | 3916 |   for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), | 
 | 3917 |        E = ClassDecl->field_end(); I != E; ++I) { | 
| David Blaikie | 581deb3 | 2012-06-06 20:45:41 +0000 | [diff] [blame] | 3918 |     FieldDecl *Field = *I; | 
| Fariborz Jahanian | 9614dc0 | 2010-05-17 18:15:18 +0000 | [diff] [blame] | 3919 |     if (Field->isInvalidDecl()) | 
 | 3920 |       continue; | 
| Douglas Gregor | ddb2147 | 2011-11-02 23:04:16 +0000 | [diff] [blame] | 3921 |      | 
 | 3922 |     // Don't destroy incomplete or zero-length arrays. | 
 | 3923 |     if (isIncompleteOrZeroLengthArrayType(Context, Field->getType())) | 
 | 3924 |       continue; | 
 | 3925 |  | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3926 |     QualType FieldType = Context.getBaseElementType(Field->getType()); | 
 | 3927 |      | 
 | 3928 |     const RecordType* RT = FieldType->getAs<RecordType>(); | 
 | 3929 |     if (!RT) | 
 | 3930 |       continue; | 
 | 3931 |      | 
 | 3932 |     CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); | 
| Matt Beaumont-Gay | 3334b0b | 2011-03-28 01:39:13 +0000 | [diff] [blame] | 3933 |     if (FieldClassDecl->isInvalidDecl()) | 
 | 3934 |       continue; | 
| Richard Smith | 213d70b | 2012-02-18 04:13:32 +0000 | [diff] [blame] | 3935 |     if (FieldClassDecl->hasIrrelevantDestructor()) | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3936 |       continue; | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 3937 |     // The destructor for an implicit anonymous union member is never invoked. | 
 | 3938 |     if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) | 
 | 3939 |       continue; | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3940 |  | 
| Douglas Gregor | db89f28 | 2010-07-01 22:47:18 +0000 | [diff] [blame] | 3941 |     CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl); | 
| Matt Beaumont-Gay | 3334b0b | 2011-03-28 01:39:13 +0000 | [diff] [blame] | 3942 |     assert(Dtor && "No dtor found for FieldClassDecl!"); | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3943 |     CheckDestructorAccess(Field->getLocation(), Dtor, | 
| Douglas Gregor | fe6b2d4 | 2010-03-29 23:34:08 +0000 | [diff] [blame] | 3944 |                           PDiag(diag::err_access_dtor_field) | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3945 |                             << Field->getDeclName() | 
 | 3946 |                             << FieldType); | 
 | 3947 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 3948 |     MarkFunctionReferenced(Location, Dtor); | 
| Richard Smith | 213d70b | 2012-02-18 04:13:32 +0000 | [diff] [blame] | 3949 |     DiagnoseUseOfDecl(Dtor, Location); | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3950 |   } | 
 | 3951 |  | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3952 |   llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases; | 
 | 3953 |  | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3954 |   // Bases. | 
 | 3955 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), | 
 | 3956 |        E = ClassDecl->bases_end(); Base != E; ++Base) { | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3957 |     // Bases are always records in a well-formed non-dependent class. | 
 | 3958 |     const RecordType *RT = Base->getType()->getAs<RecordType>(); | 
 | 3959 |  | 
 | 3960 |     // Remember direct virtual bases. | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3961 |     if (Base->isVirtual()) | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3962 |       DirectVirtualBases.insert(RT); | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3963 |  | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3964 |     CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl()); | 
| Matt Beaumont-Gay | 3334b0b | 2011-03-28 01:39:13 +0000 | [diff] [blame] | 3965 |     // If our base class is invalid, we probably can't get its dtor anyway. | 
 | 3966 |     if (BaseClassDecl->isInvalidDecl()) | 
 | 3967 |       continue; | 
| Richard Smith | 213d70b | 2012-02-18 04:13:32 +0000 | [diff] [blame] | 3968 |     if (BaseClassDecl->hasIrrelevantDestructor()) | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3969 |       continue; | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3970 |  | 
| Douglas Gregor | db89f28 | 2010-07-01 22:47:18 +0000 | [diff] [blame] | 3971 |     CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl); | 
| Matt Beaumont-Gay | 3334b0b | 2011-03-28 01:39:13 +0000 | [diff] [blame] | 3972 |     assert(Dtor && "No dtor found for BaseClassDecl!"); | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3973 |  | 
 | 3974 |     // FIXME: caret should be on the start of the class name | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 3975 |     CheckDestructorAccess(Base->getLocStart(), Dtor, | 
| Douglas Gregor | fe6b2d4 | 2010-03-29 23:34:08 +0000 | [diff] [blame] | 3976 |                           PDiag(diag::err_access_dtor_base) | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3977 |                             << Base->getType() | 
| John McCall | b9abd872 | 2012-04-07 03:04:20 +0000 | [diff] [blame] | 3978 |                             << Base->getSourceRange(), | 
 | 3979 |                           Context.getTypeDeclType(ClassDecl)); | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3980 |      | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 3981 |     MarkFunctionReferenced(Location, Dtor); | 
| Richard Smith | 213d70b | 2012-02-18 04:13:32 +0000 | [diff] [blame] | 3982 |     DiagnoseUseOfDecl(Dtor, Location); | 
| Anders Carlsson | 9f853df | 2009-11-17 04:44:12 +0000 | [diff] [blame] | 3983 |   } | 
 | 3984 |    | 
 | 3985 |   // Virtual bases. | 
| Fariborz Jahanian | 34374e6 | 2009-09-03 23:18:17 +0000 | [diff] [blame] | 3986 |   for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), | 
 | 3987 |        E = ClassDecl->vbases_end(); VBase != E; ++VBase) { | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3988 |  | 
 | 3989 |     // Bases are always records in a well-formed non-dependent class. | 
| John McCall | 63f5578 | 2012-04-09 21:51:56 +0000 | [diff] [blame] | 3990 |     const RecordType *RT = VBase->getType()->castAs<RecordType>(); | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3991 |  | 
 | 3992 |     // Ignore direct virtual bases. | 
 | 3993 |     if (DirectVirtualBases.count(RT)) | 
 | 3994 |       continue; | 
 | 3995 |  | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 3996 |     CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl()); | 
| Matt Beaumont-Gay | 3334b0b | 2011-03-28 01:39:13 +0000 | [diff] [blame] | 3997 |     // If our base class is invalid, we probably can't get its dtor anyway. | 
 | 3998 |     if (BaseClassDecl->isInvalidDecl()) | 
 | 3999 |       continue; | 
| Richard Smith | 213d70b | 2012-02-18 04:13:32 +0000 | [diff] [blame] | 4000 |     if (BaseClassDecl->hasIrrelevantDestructor()) | 
| Fariborz Jahanian | 34374e6 | 2009-09-03 23:18:17 +0000 | [diff] [blame] | 4001 |       continue; | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 4002 |  | 
| Douglas Gregor | db89f28 | 2010-07-01 22:47:18 +0000 | [diff] [blame] | 4003 |     CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl); | 
| Matt Beaumont-Gay | 3334b0b | 2011-03-28 01:39:13 +0000 | [diff] [blame] | 4004 |     assert(Dtor && "No dtor found for BaseClassDecl!"); | 
| David Majnemer | 2f68669 | 2013-06-22 06:43:58 +0000 | [diff] [blame] | 4005 |     if (CheckDestructorAccess( | 
 | 4006 |             ClassDecl->getLocation(), Dtor, | 
 | 4007 |             PDiag(diag::err_access_dtor_vbase) | 
 | 4008 |                 << Context.getTypeDeclType(ClassDecl) << VBase->getType(), | 
 | 4009 |             Context.getTypeDeclType(ClassDecl)) == | 
 | 4010 |         AR_accessible) { | 
 | 4011 |       CheckDerivedToBaseConversion( | 
 | 4012 |           Context.getTypeDeclType(ClassDecl), VBase->getType(), | 
 | 4013 |           diag::err_access_dtor_vbase, 0, ClassDecl->getLocation(), | 
 | 4014 |           SourceRange(), DeclarationName(), 0); | 
 | 4015 |     } | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 4016 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 4017 |     MarkFunctionReferenced(Location, Dtor); | 
| Richard Smith | 213d70b | 2012-02-18 04:13:32 +0000 | [diff] [blame] | 4018 |     DiagnoseUseOfDecl(Dtor, Location); | 
| Fariborz Jahanian | 34374e6 | 2009-09-03 23:18:17 +0000 | [diff] [blame] | 4019 |   } | 
 | 4020 | } | 
 | 4021 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4022 | void Sema::ActOnDefaultCtorInitializers(Decl *CDtorDecl) { | 
| Fariborz Jahanian | 560de45 | 2009-07-15 22:34:08 +0000 | [diff] [blame] | 4023 |   if (!CDtorDecl) | 
| Fariborz Jahanian | d01c915 | 2009-07-14 18:24:21 +0000 | [diff] [blame] | 4024 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4025 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4026 |   if (CXXConstructorDecl *Constructor | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4027 |       = dyn_cast<CXXConstructorDecl>(CDtorDecl)) | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 4028 |     SetCtorInitializers(Constructor, /*AnyErrors=*/false); | 
| Fariborz Jahanian | d01c915 | 2009-07-14 18:24:21 +0000 | [diff] [blame] | 4029 | } | 
 | 4030 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4031 | bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T, | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4032 |                                   unsigned DiagID, AbstractDiagSelID SelID) { | 
| Douglas Gregor | 6a26e2e | 2012-05-04 17:09:59 +0000 | [diff] [blame] | 4033 |   class NonAbstractTypeDiagnoser : public TypeDiagnoser { | 
 | 4034 |     unsigned DiagID; | 
 | 4035 |     AbstractDiagSelID SelID; | 
 | 4036 |      | 
 | 4037 |   public: | 
 | 4038 |     NonAbstractTypeDiagnoser(unsigned DiagID, AbstractDiagSelID SelID) | 
 | 4039 |       : TypeDiagnoser(DiagID == 0), DiagID(DiagID), SelID(SelID) { } | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 4040 |  | 
 | 4041 |     void diagnose(Sema &S, SourceLocation Loc, QualType T) LLVM_OVERRIDE { | 
| Eli Friedman | 2217f85 | 2012-08-14 02:06:07 +0000 | [diff] [blame] | 4042 |       if (Suppressed) return; | 
| Douglas Gregor | 6a26e2e | 2012-05-04 17:09:59 +0000 | [diff] [blame] | 4043 |       if (SelID == -1) | 
 | 4044 |         S.Diag(Loc, DiagID) << T; | 
 | 4045 |       else | 
 | 4046 |         S.Diag(Loc, DiagID) << SelID << T; | 
 | 4047 |     } | 
 | 4048 |   } Diagnoser(DiagID, SelID); | 
 | 4049 |    | 
 | 4050 |   return RequireNonAbstractType(Loc, T, Diagnoser); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4051 | } | 
 | 4052 |  | 
| Anders Carlsson | a6ec7ad | 2009-08-27 00:13:57 +0000 | [diff] [blame] | 4053 | bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T, | 
| Douglas Gregor | 6a26e2e | 2012-05-04 17:09:59 +0000 | [diff] [blame] | 4054 |                                   TypeDiagnoser &Diagnoser) { | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 4055 |   if (!getLangOpts().CPlusPlus) | 
| Anders Carlsson | 4681ebd | 2009-03-22 20:18:17 +0000 | [diff] [blame] | 4056 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4057 |  | 
| Anders Carlsson | 11f21a0 | 2009-03-23 19:10:31 +0000 | [diff] [blame] | 4058 |   if (const ArrayType *AT = Context.getAsArrayType(T)) | 
| Douglas Gregor | 6a26e2e | 2012-05-04 17:09:59 +0000 | [diff] [blame] | 4059 |     return RequireNonAbstractType(Loc, AT->getElementType(), Diagnoser); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4060 |  | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 4061 |   if (const PointerType *PT = T->getAs<PointerType>()) { | 
| Anders Carlsson | 5eff73c | 2009-03-24 01:46:45 +0000 | [diff] [blame] | 4062 |     // Find the innermost pointer type. | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 4063 |     while (const PointerType *T = PT->getPointeeType()->getAs<PointerType>()) | 
| Anders Carlsson | 5eff73c | 2009-03-24 01:46:45 +0000 | [diff] [blame] | 4064 |       PT = T; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4065 |  | 
| Anders Carlsson | 5eff73c | 2009-03-24 01:46:45 +0000 | [diff] [blame] | 4066 |     if (const ArrayType *AT = Context.getAsArrayType(PT->getPointeeType())) | 
| Douglas Gregor | 6a26e2e | 2012-05-04 17:09:59 +0000 | [diff] [blame] | 4067 |       return RequireNonAbstractType(Loc, AT->getElementType(), Diagnoser); | 
| Anders Carlsson | 5eff73c | 2009-03-24 01:46:45 +0000 | [diff] [blame] | 4068 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4069 |  | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 4070 |   const RecordType *RT = T->getAs<RecordType>(); | 
| Anders Carlsson | 4681ebd | 2009-03-22 20:18:17 +0000 | [diff] [blame] | 4071 |   if (!RT) | 
 | 4072 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4073 |  | 
| John McCall | 86ff308 | 2010-02-04 22:26:26 +0000 | [diff] [blame] | 4074 |   const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); | 
| Anders Carlsson | 4681ebd | 2009-03-22 20:18:17 +0000 | [diff] [blame] | 4075 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4076 |   // We can't answer whether something is abstract until it has a | 
 | 4077 |   // definition.  If it's currently being defined, we'll walk back | 
 | 4078 |   // over all the declarations when we have a full definition. | 
 | 4079 |   const CXXRecordDecl *Def = RD->getDefinition(); | 
 | 4080 |   if (!Def || Def->isBeingDefined()) | 
| John McCall | 86ff308 | 2010-02-04 22:26:26 +0000 | [diff] [blame] | 4081 |     return false; | 
 | 4082 |  | 
| Anders Carlsson | 4681ebd | 2009-03-22 20:18:17 +0000 | [diff] [blame] | 4083 |   if (!RD->isAbstract()) | 
 | 4084 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4085 |  | 
| Douglas Gregor | 6a26e2e | 2012-05-04 17:09:59 +0000 | [diff] [blame] | 4086 |   Diagnoser.diagnose(*this, Loc, T); | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4087 |   DiagnoseAbstractType(RD); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4088 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4089 |   return true; | 
 | 4090 | } | 
 | 4091 |  | 
 | 4092 | void Sema::DiagnoseAbstractType(const CXXRecordDecl *RD) { | 
 | 4093 |   // Check if we've already emitted the list of pure virtual functions | 
 | 4094 |   // for this class. | 
| Anders Carlsson | 4681ebd | 2009-03-22 20:18:17 +0000 | [diff] [blame] | 4095 |   if (PureVirtualClassDiagSet && PureVirtualClassDiagSet->count(RD)) | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4096 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4097 |  | 
| Richard Smith | cbc820a | 2013-07-22 02:56:56 +0000 | [diff] [blame] | 4098 |   // If the diagnostic is suppressed, don't emit the notes. We're only | 
 | 4099 |   // going to emit them once, so try to attach them to a diagnostic we're | 
 | 4100 |   // actually going to show. | 
 | 4101 |   if (Diags.isLastDiagnosticIgnored()) | 
 | 4102 |     return; | 
 | 4103 |  | 
| Douglas Gregor | 7b2fc9d | 2010-03-23 23:47:56 +0000 | [diff] [blame] | 4104 |   CXXFinalOverriderMap FinalOverriders; | 
 | 4105 |   RD->getFinalOverriders(FinalOverriders); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4106 |  | 
| Anders Carlsson | ffdb2d2 | 2010-06-03 01:00:02 +0000 | [diff] [blame] | 4107 |   // Keep a set of seen pure methods so we won't diagnose the same method | 
 | 4108 |   // more than once. | 
 | 4109 |   llvm::SmallPtrSet<const CXXMethodDecl *, 8> SeenPureMethods; | 
 | 4110 |    | 
| Douglas Gregor | 7b2fc9d | 2010-03-23 23:47:56 +0000 | [diff] [blame] | 4111 |   for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(),  | 
 | 4112 |                                    MEnd = FinalOverriders.end(); | 
 | 4113 |        M != MEnd;  | 
 | 4114 |        ++M) { | 
 | 4115 |     for (OverridingMethods::iterator SO = M->second.begin(),  | 
 | 4116 |                                   SOEnd = M->second.end(); | 
 | 4117 |          SO != SOEnd; ++SO) { | 
 | 4118 |       // C++ [class.abstract]p4: | 
 | 4119 |       //   A class is abstract if it contains or inherits at least one | 
 | 4120 |       //   pure virtual function for which the final overrider is pure | 
 | 4121 |       //   virtual. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4122 |  | 
| Douglas Gregor | 7b2fc9d | 2010-03-23 23:47:56 +0000 | [diff] [blame] | 4123 |       //  | 
 | 4124 |       if (SO->second.size() != 1) | 
 | 4125 |         continue; | 
 | 4126 |  | 
 | 4127 |       if (!SO->second.front().Method->isPure()) | 
 | 4128 |         continue; | 
 | 4129 |  | 
| Anders Carlsson | ffdb2d2 | 2010-06-03 01:00:02 +0000 | [diff] [blame] | 4130 |       if (!SeenPureMethods.insert(SO->second.front().Method)) | 
 | 4131 |         continue; | 
 | 4132 |  | 
| Douglas Gregor | 7b2fc9d | 2010-03-23 23:47:56 +0000 | [diff] [blame] | 4133 |       Diag(SO->second.front().Method->getLocation(),  | 
 | 4134 |            diag::note_pure_virtual_function)  | 
| Chandler Carruth | 45f11b7 | 2011-02-18 23:59:51 +0000 | [diff] [blame] | 4135 |         << SO->second.front().Method->getDeclName() << RD->getDeclName(); | 
| Douglas Gregor | 7b2fc9d | 2010-03-23 23:47:56 +0000 | [diff] [blame] | 4136 |     } | 
| Anders Carlsson | 4681ebd | 2009-03-22 20:18:17 +0000 | [diff] [blame] | 4137 |   } | 
 | 4138 |  | 
 | 4139 |   if (!PureVirtualClassDiagSet) | 
 | 4140 |     PureVirtualClassDiagSet.reset(new RecordDeclSetTy); | 
 | 4141 |   PureVirtualClassDiagSet->insert(RD); | 
| Anders Carlsson | 4681ebd | 2009-03-22 20:18:17 +0000 | [diff] [blame] | 4142 | } | 
 | 4143 |  | 
| Anders Carlsson | 8211eff | 2009-03-24 01:19:16 +0000 | [diff] [blame] | 4144 | namespace { | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4145 | struct AbstractUsageInfo { | 
 | 4146 |   Sema &S; | 
 | 4147 |   CXXRecordDecl *Record; | 
 | 4148 |   CanQualType AbstractType; | 
 | 4149 |   bool Invalid; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4150 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4151 |   AbstractUsageInfo(Sema &S, CXXRecordDecl *Record) | 
 | 4152 |     : S(S), Record(Record), | 
 | 4153 |       AbstractType(S.Context.getCanonicalType( | 
 | 4154 |                    S.Context.getTypeDeclType(Record))), | 
 | 4155 |       Invalid(false) {} | 
| Anders Carlsson | 8211eff | 2009-03-24 01:19:16 +0000 | [diff] [blame] | 4156 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4157 |   void DiagnoseAbstractType() { | 
 | 4158 |     if (Invalid) return; | 
 | 4159 |     S.DiagnoseAbstractType(Record); | 
 | 4160 |     Invalid = true; | 
 | 4161 |   } | 
| Anders Carlsson | e65a3c8 | 2009-03-24 17:23:42 +0000 | [diff] [blame] | 4162 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4163 |   void CheckType(const NamedDecl *D, TypeLoc TL, Sema::AbstractDiagSelID Sel); | 
 | 4164 | }; | 
 | 4165 |  | 
 | 4166 | struct CheckAbstractUsage { | 
 | 4167 |   AbstractUsageInfo &Info; | 
 | 4168 |   const NamedDecl *Ctx; | 
 | 4169 |  | 
 | 4170 |   CheckAbstractUsage(AbstractUsageInfo &Info, const NamedDecl *Ctx) | 
 | 4171 |     : Info(Info), Ctx(Ctx) {} | 
 | 4172 |  | 
 | 4173 |   void Visit(TypeLoc TL, Sema::AbstractDiagSelID Sel) { | 
 | 4174 |     switch (TL.getTypeLocClass()) { | 
 | 4175 | #define ABSTRACT_TYPELOC(CLASS, PARENT) | 
 | 4176 | #define TYPELOC(CLASS, PARENT) \ | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 4177 |     case TypeLoc::CLASS: Check(TL.castAs<CLASS##TypeLoc>(), Sel); break; | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4178 | #include "clang/AST/TypeLocNodes.def" | 
| Anders Carlsson | 8211eff | 2009-03-24 01:19:16 +0000 | [diff] [blame] | 4179 |     } | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4180 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4181 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4182 |   void Check(FunctionProtoTypeLoc TL, Sema::AbstractDiagSelID Sel) { | 
 | 4183 |     Visit(TL.getResultLoc(), Sema::AbstractReturnType); | 
 | 4184 |     for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { | 
| Douglas Gregor | 7019186 | 2011-02-22 23:21:06 +0000 | [diff] [blame] | 4185 |       if (!TL.getArg(I)) | 
 | 4186 |         continue; | 
 | 4187 |        | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4188 |       TypeSourceInfo *TSI = TL.getArg(I)->getTypeSourceInfo(); | 
 | 4189 |       if (TSI) Visit(TSI->getTypeLoc(), Sema::AbstractParamType); | 
| Anders Carlsson | e65a3c8 | 2009-03-24 17:23:42 +0000 | [diff] [blame] | 4190 |     } | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4191 |   } | 
| Anders Carlsson | 8211eff | 2009-03-24 01:19:16 +0000 | [diff] [blame] | 4192 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4193 |   void Check(ArrayTypeLoc TL, Sema::AbstractDiagSelID Sel) { | 
 | 4194 |     Visit(TL.getElementLoc(), Sema::AbstractArrayType); | 
 | 4195 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4196 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4197 |   void Check(TemplateSpecializationTypeLoc TL, Sema::AbstractDiagSelID Sel) { | 
 | 4198 |     // Visit the type parameters from a permissive context. | 
 | 4199 |     for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { | 
 | 4200 |       TemplateArgumentLoc TAL = TL.getArgLoc(I); | 
 | 4201 |       if (TAL.getArgument().getKind() == TemplateArgument::Type) | 
 | 4202 |         if (TypeSourceInfo *TSI = TAL.getTypeSourceInfo()) | 
 | 4203 |           Visit(TSI->getTypeLoc(), Sema::AbstractNone); | 
 | 4204 |       // TODO: other template argument types? | 
| Anders Carlsson | 8211eff | 2009-03-24 01:19:16 +0000 | [diff] [blame] | 4205 |     } | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4206 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4207 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4208 |   // Visit pointee types from a permissive context. | 
 | 4209 | #define CheckPolymorphic(Type) \ | 
 | 4210 |   void Check(Type TL, Sema::AbstractDiagSelID Sel) { \ | 
 | 4211 |     Visit(TL.getNextTypeLoc(), Sema::AbstractNone); \ | 
 | 4212 |   } | 
 | 4213 |   CheckPolymorphic(PointerTypeLoc) | 
 | 4214 |   CheckPolymorphic(ReferenceTypeLoc) | 
 | 4215 |   CheckPolymorphic(MemberPointerTypeLoc) | 
 | 4216 |   CheckPolymorphic(BlockPointerTypeLoc) | 
| Eli Friedman | b001de7 | 2011-10-06 23:00:33 +0000 | [diff] [blame] | 4217 |   CheckPolymorphic(AtomicTypeLoc) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4218 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4219 |   /// Handle all the types we haven't given a more specific | 
 | 4220 |   /// implementation for above. | 
 | 4221 |   void Check(TypeLoc TL, Sema::AbstractDiagSelID Sel) { | 
 | 4222 |     // Every other kind of type that we haven't called out already | 
 | 4223 |     // that has an inner type is either (1) sugar or (2) contains that | 
 | 4224 |     // inner type in some way as a subobject. | 
 | 4225 |     if (TypeLoc Next = TL.getNextTypeLoc()) | 
 | 4226 |       return Visit(Next, Sel); | 
 | 4227 |  | 
 | 4228 |     // If there's no inner type and we're in a permissive context, | 
 | 4229 |     // don't diagnose. | 
 | 4230 |     if (Sel == Sema::AbstractNone) return; | 
 | 4231 |  | 
 | 4232 |     // Check whether the type matches the abstract type. | 
 | 4233 |     QualType T = TL.getType(); | 
 | 4234 |     if (T->isArrayType()) { | 
 | 4235 |       Sel = Sema::AbstractArrayType; | 
 | 4236 |       T = Info.S.Context.getBaseElementType(T); | 
| Anders Carlsson | e65a3c8 | 2009-03-24 17:23:42 +0000 | [diff] [blame] | 4237 |     } | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4238 |     CanQualType CT = T->getCanonicalTypeUnqualified().getUnqualifiedType(); | 
 | 4239 |     if (CT != Info.AbstractType) return; | 
 | 4240 |  | 
 | 4241 |     // It matched; do some magic. | 
 | 4242 |     if (Sel == Sema::AbstractArrayType) { | 
 | 4243 |       Info.S.Diag(Ctx->getLocation(), diag::err_array_of_abstract_type) | 
 | 4244 |         << T << TL.getSourceRange(); | 
 | 4245 |     } else { | 
 | 4246 |       Info.S.Diag(Ctx->getLocation(), diag::err_abstract_type_in_decl) | 
 | 4247 |         << Sel << T << TL.getSourceRange(); | 
 | 4248 |     } | 
 | 4249 |     Info.DiagnoseAbstractType(); | 
 | 4250 |   } | 
 | 4251 | }; | 
 | 4252 |  | 
 | 4253 | void AbstractUsageInfo::CheckType(const NamedDecl *D, TypeLoc TL, | 
 | 4254 |                                   Sema::AbstractDiagSelID Sel) { | 
 | 4255 |   CheckAbstractUsage(*this, D).Visit(TL, Sel); | 
 | 4256 | } | 
 | 4257 |  | 
 | 4258 | } | 
 | 4259 |  | 
 | 4260 | /// Check for invalid uses of an abstract type in a method declaration. | 
 | 4261 | static void CheckAbstractClassUsage(AbstractUsageInfo &Info, | 
 | 4262 |                                     CXXMethodDecl *MD) { | 
 | 4263 |   // No need to do the check on definitions, which require that | 
 | 4264 |   // the return/param types be complete. | 
| Sean Hunt | 10620eb | 2011-05-06 20:44:56 +0000 | [diff] [blame] | 4265 |   if (MD->doesThisDeclarationHaveABody()) | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4266 |     return; | 
 | 4267 |  | 
 | 4268 |   // For safety's sake, just ignore it if we don't have type source | 
 | 4269 |   // information.  This should never happen for non-implicit methods, | 
 | 4270 |   // but... | 
 | 4271 |   if (TypeSourceInfo *TSI = MD->getTypeSourceInfo()) | 
 | 4272 |     Info.CheckType(MD, TSI->getTypeLoc(), Sema::AbstractNone); | 
 | 4273 | } | 
 | 4274 |  | 
 | 4275 | /// Check for invalid uses of an abstract type within a class definition. | 
 | 4276 | static void CheckAbstractClassUsage(AbstractUsageInfo &Info, | 
 | 4277 |                                     CXXRecordDecl *RD) { | 
 | 4278 |   for (CXXRecordDecl::decl_iterator | 
 | 4279 |          I = RD->decls_begin(), E = RD->decls_end(); I != E; ++I) { | 
 | 4280 |     Decl *D = *I; | 
 | 4281 |     if (D->isImplicit()) continue; | 
 | 4282 |  | 
 | 4283 |     // Methods and method templates. | 
 | 4284 |     if (isa<CXXMethodDecl>(D)) { | 
 | 4285 |       CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(D)); | 
 | 4286 |     } else if (isa<FunctionTemplateDecl>(D)) { | 
 | 4287 |       FunctionDecl *FD = cast<FunctionTemplateDecl>(D)->getTemplatedDecl(); | 
 | 4288 |       CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(FD)); | 
 | 4289 |  | 
 | 4290 |     // Fields and static variables. | 
 | 4291 |     } else if (isa<FieldDecl>(D)) { | 
 | 4292 |       FieldDecl *FD = cast<FieldDecl>(D); | 
 | 4293 |       if (TypeSourceInfo *TSI = FD->getTypeSourceInfo()) | 
 | 4294 |         Info.CheckType(FD, TSI->getTypeLoc(), Sema::AbstractFieldType); | 
 | 4295 |     } else if (isa<VarDecl>(D)) { | 
 | 4296 |       VarDecl *VD = cast<VarDecl>(D); | 
 | 4297 |       if (TypeSourceInfo *TSI = VD->getTypeSourceInfo()) | 
 | 4298 |         Info.CheckType(VD, TSI->getTypeLoc(), Sema::AbstractVariableType); | 
 | 4299 |  | 
 | 4300 |     // Nested classes and class templates. | 
 | 4301 |     } else if (isa<CXXRecordDecl>(D)) { | 
 | 4302 |       CheckAbstractClassUsage(Info, cast<CXXRecordDecl>(D)); | 
 | 4303 |     } else if (isa<ClassTemplateDecl>(D)) { | 
 | 4304 |       CheckAbstractClassUsage(Info, | 
 | 4305 |                              cast<ClassTemplateDecl>(D)->getTemplatedDecl()); | 
 | 4306 |     } | 
 | 4307 |   } | 
| Anders Carlsson | 8211eff | 2009-03-24 01:19:16 +0000 | [diff] [blame] | 4308 | } | 
 | 4309 |  | 
| Douglas Gregor | 1ab537b | 2009-12-03 18:33:45 +0000 | [diff] [blame] | 4310 | /// \brief Perform semantic checks on a class definition that has been | 
 | 4311 | /// completing, introducing implicitly-declared members, checking for | 
 | 4312 | /// abstract types, etc. | 
| Douglas Gregor | 23c94db | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 4313 | void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { | 
| Douglas Gregor | 7a39dd0 | 2010-09-29 00:15:42 +0000 | [diff] [blame] | 4314 |   if (!Record) | 
| Douglas Gregor | 1ab537b | 2009-12-03 18:33:45 +0000 | [diff] [blame] | 4315 |     return; | 
 | 4316 |  | 
| John McCall | 94c3b56 | 2010-08-18 09:41:07 +0000 | [diff] [blame] | 4317 |   if (Record->isAbstract() && !Record->isInvalidDecl()) { | 
 | 4318 |     AbstractUsageInfo Info(*this, Record); | 
 | 4319 |     CheckAbstractClassUsage(Info, Record); | 
 | 4320 |   } | 
| Douglas Gregor | 325e593 | 2010-04-15 00:00:53 +0000 | [diff] [blame] | 4321 |    | 
 | 4322 |   // If this is not an aggregate type and has no user-declared constructor, | 
 | 4323 |   // complain about any non-static data members of reference or const scalar | 
 | 4324 |   // type, since they will never get initializers. | 
 | 4325 |   if (!Record->isInvalidDecl() && !Record->isDependentType() && | 
| Douglas Gregor | 5e058eb | 2012-02-09 02:20:38 +0000 | [diff] [blame] | 4326 |       !Record->isAggregate() && !Record->hasUserDeclaredConstructor() && | 
 | 4327 |       !Record->isLambda()) { | 
| Douglas Gregor | 325e593 | 2010-04-15 00:00:53 +0000 | [diff] [blame] | 4328 |     bool Complained = false; | 
 | 4329 |     for (RecordDecl::field_iterator F = Record->field_begin(),  | 
 | 4330 |                                  FEnd = Record->field_end(); | 
 | 4331 |          F != FEnd; ++F) { | 
| Douglas Gregor | d61db33 | 2011-10-10 17:22:13 +0000 | [diff] [blame] | 4332 |       if (F->hasInClassInitializer() || F->isUnnamedBitfield()) | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 4333 |         continue; | 
 | 4334 |  | 
| Douglas Gregor | 325e593 | 2010-04-15 00:00:53 +0000 | [diff] [blame] | 4335 |       if (F->getType()->isReferenceType() || | 
| Benjamin Kramer | 1deea66 | 2010-04-16 17:43:15 +0000 | [diff] [blame] | 4336 |           (F->getType().isConstQualified() && F->getType()->isScalarType())) { | 
| Douglas Gregor | 325e593 | 2010-04-15 00:00:53 +0000 | [diff] [blame] | 4337 |         if (!Complained) { | 
 | 4338 |           Diag(Record->getLocation(), diag::warn_no_constructor_for_refconst) | 
 | 4339 |             << Record->getTagKind() << Record; | 
 | 4340 |           Complained = true; | 
 | 4341 |         } | 
 | 4342 |          | 
 | 4343 |         Diag(F->getLocation(), diag::note_refconst_member_not_initialized) | 
 | 4344 |           << F->getType()->isReferenceType() | 
 | 4345 |           << F->getDeclName(); | 
 | 4346 |       } | 
 | 4347 |     } | 
 | 4348 |   } | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 4349 |  | 
| Anders Carlsson | a5c6c2a | 2011-01-25 18:08:22 +0000 | [diff] [blame] | 4350 |   if (Record->isDynamicClass() && !Record->isDependentType()) | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 4351 |     DynamicClasses.push_back(Record); | 
| Douglas Gregor | a6e937c | 2010-10-15 13:21:21 +0000 | [diff] [blame] | 4352 |  | 
 | 4353 |   if (Record->getIdentifier()) { | 
 | 4354 |     // C++ [class.mem]p13: | 
 | 4355 |     //   If T is the name of a class, then each of the following shall have a  | 
 | 4356 |     //   name different from T: | 
 | 4357 |     //     - every member of every anonymous union that is a member of class T. | 
 | 4358 |     // | 
 | 4359 |     // C++ [class.mem]p14: | 
 | 4360 |     //   In addition, if class T has a user-declared constructor (12.1), every  | 
 | 4361 |     //   non-static data member of class T shall have a name different from T. | 
| David Blaikie | 3bc93e3 | 2012-12-19 00:45:41 +0000 | [diff] [blame] | 4362 |     DeclContext::lookup_result R = Record->lookup(Record->getDeclName()); | 
 | 4363 |     for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; | 
 | 4364 |          ++I) { | 
 | 4365 |       NamedDecl *D = *I; | 
| Francois Pichet | 87c2e12 | 2010-11-21 06:08:52 +0000 | [diff] [blame] | 4366 |       if ((isa<FieldDecl>(D) && Record->hasUserDeclaredConstructor()) || | 
 | 4367 |           isa<IndirectFieldDecl>(D)) { | 
 | 4368 |         Diag(D->getLocation(), diag::err_member_name_of_class) | 
 | 4369 |           << D->getDeclName(); | 
| Douglas Gregor | a6e937c | 2010-10-15 13:21:21 +0000 | [diff] [blame] | 4370 |         break; | 
 | 4371 |       } | 
| Francois Pichet | 87c2e12 | 2010-11-21 06:08:52 +0000 | [diff] [blame] | 4372 |     } | 
| Douglas Gregor | a6e937c | 2010-10-15 13:21:21 +0000 | [diff] [blame] | 4373 |   } | 
| Argyrios Kyrtzidis | def4e2a | 2011-01-31 07:05:00 +0000 | [diff] [blame] | 4374 |  | 
| Argyrios Kyrtzidis | 9641fc8 | 2011-01-31 17:10:25 +0000 | [diff] [blame] | 4375 |   // Warn if the class has virtual methods but non-virtual public destructor. | 
| Douglas Gregor | f4b793c | 2011-02-19 19:14:36 +0000 | [diff] [blame] | 4376 |   if (Record->isPolymorphic() && !Record->isDependentType()) { | 
| Argyrios Kyrtzidis | def4e2a | 2011-01-31 07:05:00 +0000 | [diff] [blame] | 4377 |     CXXDestructorDecl *dtor = Record->getDestructor(); | 
| Argyrios Kyrtzidis | 9641fc8 | 2011-01-31 17:10:25 +0000 | [diff] [blame] | 4378 |     if (!dtor || (!dtor->isVirtual() && dtor->getAccess() == AS_public)) | 
| Argyrios Kyrtzidis | def4e2a | 2011-01-31 07:05:00 +0000 | [diff] [blame] | 4379 |       Diag(dtor ? dtor->getLocation() : Record->getLocation(), | 
 | 4380 |            diag::warn_non_virtual_dtor) << Context.getRecordType(Record); | 
 | 4381 |   } | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 4382 |  | 
| David Blaikie | b6b5b97 | 2012-09-21 03:21:07 +0000 | [diff] [blame] | 4383 |   if (Record->isAbstract() && Record->hasAttr<FinalAttr>()) { | 
 | 4384 |     Diag(Record->getLocation(), diag::warn_abstract_final_class); | 
 | 4385 |     DiagnoseAbstractType(Record); | 
 | 4386 |   } | 
 | 4387 |  | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 4388 |   if (!Record->isDependentType()) { | 
 | 4389 |     for (CXXRecordDecl::method_iterator M = Record->method_begin(), | 
 | 4390 |                                      MEnd = Record->method_end(); | 
 | 4391 |          M != MEnd; ++M) { | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4392 |       // See if a method overloads virtual methods in a base | 
 | 4393 |       // class without overriding any. | 
| David Blaikie | 262bc18 | 2012-04-30 02:36:29 +0000 | [diff] [blame] | 4394 |       if (!M->isStatic()) | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 4395 |         DiagnoseHiddenVirtualMethods(*M); | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4396 |  | 
 | 4397 |       // Check whether the explicitly-defaulted special members are valid. | 
 | 4398 |       if (!M->isInvalidDecl() && M->isExplicitlyDefaulted()) | 
 | 4399 |         CheckExplicitlyDefaultedSpecialMember(*M); | 
 | 4400 |  | 
 | 4401 |       // For an explicitly defaulted or deleted special member, we defer | 
 | 4402 |       // determining triviality until the class is complete. That time is now! | 
 | 4403 |       if (!M->isImplicit() && !M->isUserProvided()) { | 
 | 4404 |         CXXSpecialMember CSM = getSpecialMember(*M); | 
 | 4405 |         if (CSM != CXXInvalid) { | 
 | 4406 |           M->setTrivial(SpecialMemberIsTrivial(*M, CSM)); | 
 | 4407 |  | 
 | 4408 |           // Inform the class that we've finished declaring this member. | 
 | 4409 |           Record->finishedDefaultedOrDeletedMember(*M); | 
 | 4410 |         } | 
 | 4411 |       } | 
 | 4412 |     } | 
 | 4413 |   } | 
 | 4414 |  | 
 | 4415 |   // C++11 [dcl.constexpr]p8: A constexpr specifier for a non-static member | 
 | 4416 |   // function that is not a constructor declares that member function to be | 
 | 4417 |   // const. [...] The class of which that function is a member shall be | 
 | 4418 |   // a literal type. | 
 | 4419 |   // | 
 | 4420 |   // If the class has virtual bases, any constexpr members will already have | 
 | 4421 |   // been diagnosed by the checks performed on the member declaration, so | 
 | 4422 |   // suppress this (less useful) diagnostic. | 
 | 4423 |   // | 
 | 4424 |   // We delay this until we know whether an explicitly-defaulted (or deleted) | 
 | 4425 |   // destructor for the class is trivial. | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 4426 |   if (LangOpts.CPlusPlus11 && !Record->isDependentType() && | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4427 |       !Record->isLiteral() && !Record->getNumVBases()) { | 
 | 4428 |     for (CXXRecordDecl::method_iterator M = Record->method_begin(), | 
 | 4429 |                                      MEnd = Record->method_end(); | 
 | 4430 |          M != MEnd; ++M) { | 
 | 4431 |       if (M->isConstexpr() && M->isInstance() && !isa<CXXConstructorDecl>(*M)) { | 
 | 4432 |         switch (Record->getTemplateSpecializationKind()) { | 
 | 4433 |         case TSK_ImplicitInstantiation: | 
 | 4434 |         case TSK_ExplicitInstantiationDeclaration: | 
 | 4435 |         case TSK_ExplicitInstantiationDefinition: | 
 | 4436 |           // If a template instantiates to a non-literal type, but its members | 
 | 4437 |           // instantiate to constexpr functions, the template is technically | 
 | 4438 |           // ill-formed, but we allow it for sanity. | 
 | 4439 |           continue; | 
 | 4440 |  | 
 | 4441 |         case TSK_Undeclared: | 
 | 4442 |         case TSK_ExplicitSpecialization: | 
 | 4443 |           RequireLiteralType(M->getLocation(), Context.getRecordType(Record), | 
 | 4444 |                              diag::err_constexpr_method_non_literal); | 
 | 4445 |           break; | 
 | 4446 |         } | 
 | 4447 |  | 
 | 4448 |         // Only produce one error per class. | 
 | 4449 |         break; | 
 | 4450 |       } | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 4451 |     } | 
 | 4452 |   } | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 4453 |  | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 4454 |   // Declare inheriting constructors. We do this eagerly here because: | 
 | 4455 |   // - The standard requires an eager diagnostic for conflicting inheriting | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 4456 |   //   constructors from different classes. | 
 | 4457 |   // - The lazy declaration of the other implicit constructors is so as to not | 
 | 4458 |   //   waste space and performance on classes that are not meant to be | 
 | 4459 |   //   instantiated (e.g. meta-functions). This doesn't apply to classes that | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 4460 |   //   have inheriting constructors. | 
 | 4461 |   DeclareInheritingConstructors(Record); | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 4462 | } | 
 | 4463 |  | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4464 | /// Is the special member function which would be selected to perform the | 
 | 4465 | /// specified operation on the specified class type a constexpr constructor? | 
 | 4466 | static bool specialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl, | 
 | 4467 |                                      Sema::CXXSpecialMember CSM, | 
 | 4468 |                                      bool ConstArg) { | 
 | 4469 |   Sema::SpecialMemberOverloadResult *SMOR = | 
 | 4470 |       S.LookupSpecialMember(ClassDecl, CSM, ConstArg, | 
 | 4471 |                             false, false, false, false); | 
 | 4472 |   if (!SMOR || !SMOR->getMethod()) | 
 | 4473 |     // A constructor we wouldn't select can't be "involved in initializing" | 
 | 4474 |     // anything. | 
 | 4475 |     return true; | 
 | 4476 |   return SMOR->getMethod()->isConstexpr(); | 
 | 4477 | } | 
 | 4478 |  | 
 | 4479 | /// Determine whether the specified special member function would be constexpr | 
 | 4480 | /// if it were implicitly defined. | 
 | 4481 | static bool defaultedSpecialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl, | 
 | 4482 |                                               Sema::CXXSpecialMember CSM, | 
 | 4483 |                                               bool ConstArg) { | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 4484 |   if (!S.getLangOpts().CPlusPlus11) | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4485 |     return false; | 
 | 4486 |  | 
 | 4487 |   // C++11 [dcl.constexpr]p4: | 
 | 4488 |   // In the definition of a constexpr constructor [...] | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4489 |   bool Ctor = true; | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4490 |   switch (CSM) { | 
 | 4491 |   case Sema::CXXDefaultConstructor: | 
| Richard Smith | d3861ce | 2012-06-10 07:07:24 +0000 | [diff] [blame] | 4492 |     // Since default constructor lookup is essentially trivial (and cannot | 
 | 4493 |     // involve, for instance, template instantiation), we compute whether a | 
 | 4494 |     // defaulted default constructor is constexpr directly within CXXRecordDecl. | 
 | 4495 |     // | 
 | 4496 |     // This is important for performance; we need to know whether the default | 
 | 4497 |     // constructor is constexpr to determine whether the type is a literal type. | 
 | 4498 |     return ClassDecl->defaultedDefaultConstructorIsConstexpr(); | 
 | 4499 |  | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4500 |   case Sema::CXXCopyConstructor: | 
 | 4501 |   case Sema::CXXMoveConstructor: | 
| Richard Smith | d3861ce | 2012-06-10 07:07:24 +0000 | [diff] [blame] | 4502 |     // For copy or move constructors, we need to perform overload resolution. | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4503 |     break; | 
 | 4504 |  | 
 | 4505 |   case Sema::CXXCopyAssignment: | 
 | 4506 |   case Sema::CXXMoveAssignment: | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4507 |     if (!S.getLangOpts().CPlusPlus1y) | 
 | 4508 |       return false; | 
 | 4509 |     // In C++1y, we need to perform overload resolution. | 
 | 4510 |     Ctor = false; | 
 | 4511 |     break; | 
 | 4512 |  | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4513 |   case Sema::CXXDestructor: | 
 | 4514 |   case Sema::CXXInvalid: | 
 | 4515 |     return false; | 
 | 4516 |   } | 
 | 4517 |  | 
 | 4518 |   //   -- if the class is a non-empty union, or for each non-empty anonymous | 
 | 4519 |   //      union member of a non-union class, exactly one non-static data member | 
 | 4520 |   //      shall be initialized; [DR1359] | 
| Richard Smith | d3861ce | 2012-06-10 07:07:24 +0000 | [diff] [blame] | 4521 |   // | 
 | 4522 |   // If we squint, this is guaranteed, since exactly one non-static data member | 
 | 4523 |   // will be initialized (if the constructor isn't deleted), we just don't know | 
 | 4524 |   // which one. | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4525 |   if (Ctor && ClassDecl->isUnion()) | 
| Richard Smith | d3861ce | 2012-06-10 07:07:24 +0000 | [diff] [blame] | 4526 |     return true; | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4527 |  | 
 | 4528 |   //   -- the class shall not have any virtual base classes; | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4529 |   if (Ctor && ClassDecl->getNumVBases()) | 
 | 4530 |     return false; | 
 | 4531 |  | 
 | 4532 |   // C++1y [class.copy]p26: | 
 | 4533 |   //   -- [the class] is a literal type, and | 
 | 4534 |   if (!Ctor && !ClassDecl->isLiteral()) | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4535 |     return false; | 
 | 4536 |  | 
 | 4537 |   //   -- every constructor involved in initializing [...] base class | 
 | 4538 |   //      sub-objects shall be a constexpr constructor; | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4539 |   //   -- the assignment operator selected to copy/move each direct base | 
 | 4540 |   //      class is a constexpr function, and | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4541 |   for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(), | 
 | 4542 |                                        BEnd = ClassDecl->bases_end(); | 
 | 4543 |        B != BEnd; ++B) { | 
 | 4544 |     const RecordType *BaseType = B->getType()->getAs<RecordType>(); | 
 | 4545 |     if (!BaseType) continue; | 
 | 4546 |  | 
 | 4547 |     CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); | 
 | 4548 |     if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, ConstArg)) | 
 | 4549 |       return false; | 
 | 4550 |   } | 
 | 4551 |  | 
 | 4552 |   //   -- every constructor involved in initializing non-static data members | 
 | 4553 |   //      [...] shall be a constexpr constructor; | 
 | 4554 |   //   -- every non-static data member and base class sub-object shall be | 
 | 4555 |   //      initialized | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4556 |   //   -- for each non-stastic data member of X that is of class type (or array | 
 | 4557 |   //      thereof), the assignment operator selected to copy/move that member is | 
 | 4558 |   //      a constexpr function | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4559 |   for (RecordDecl::field_iterator F = ClassDecl->field_begin(), | 
 | 4560 |                                FEnd = ClassDecl->field_end(); | 
 | 4561 |        F != FEnd; ++F) { | 
 | 4562 |     if (F->isInvalidDecl()) | 
 | 4563 |       continue; | 
| Richard Smith | d3861ce | 2012-06-10 07:07:24 +0000 | [diff] [blame] | 4564 |     if (const RecordType *RecordTy = | 
 | 4565 |             S.Context.getBaseElementType(F->getType())->getAs<RecordType>()) { | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4566 |       CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); | 
 | 4567 |       if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM, ConstArg)) | 
 | 4568 |         return false; | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4569 |     } | 
 | 4570 |   } | 
 | 4571 |  | 
 | 4572 |   // All OK, it's constexpr! | 
 | 4573 |   return true; | 
 | 4574 | } | 
 | 4575 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 4576 | static Sema::ImplicitExceptionSpecification | 
 | 4577 | computeImplicitExceptionSpec(Sema &S, SourceLocation Loc, CXXMethodDecl *MD) { | 
 | 4578 |   switch (S.getSpecialMember(MD)) { | 
 | 4579 |   case Sema::CXXDefaultConstructor: | 
 | 4580 |     return S.ComputeDefaultedDefaultCtorExceptionSpec(Loc, MD); | 
 | 4581 |   case Sema::CXXCopyConstructor: | 
 | 4582 |     return S.ComputeDefaultedCopyCtorExceptionSpec(MD); | 
 | 4583 |   case Sema::CXXCopyAssignment: | 
 | 4584 |     return S.ComputeDefaultedCopyAssignmentExceptionSpec(MD); | 
 | 4585 |   case Sema::CXXMoveConstructor: | 
 | 4586 |     return S.ComputeDefaultedMoveCtorExceptionSpec(MD); | 
 | 4587 |   case Sema::CXXMoveAssignment: | 
 | 4588 |     return S.ComputeDefaultedMoveAssignmentExceptionSpec(MD); | 
 | 4589 |   case Sema::CXXDestructor: | 
 | 4590 |     return S.ComputeDefaultedDtorExceptionSpec(MD); | 
 | 4591 |   case Sema::CXXInvalid: | 
 | 4592 |     break; | 
 | 4593 |   } | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 4594 |   assert(cast<CXXConstructorDecl>(MD)->getInheritedConstructor() && | 
 | 4595 |          "only special members have implicit exception specs"); | 
 | 4596 |   return S.ComputeInheritingCtorExceptionSpec(cast<CXXConstructorDecl>(MD)); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 4597 | } | 
 | 4598 |  | 
| Richard Smith | dd25e80 | 2012-07-30 23:48:14 +0000 | [diff] [blame] | 4599 | static void | 
 | 4600 | updateExceptionSpec(Sema &S, FunctionDecl *FD, const FunctionProtoType *FPT, | 
 | 4601 |                     const Sema::ImplicitExceptionSpecification &ExceptSpec) { | 
 | 4602 |   FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); | 
 | 4603 |   ExceptSpec.getEPI(EPI); | 
| Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 4604 |   FD->setType(S.Context.getFunctionType(FPT->getResultType(), | 
 | 4605 |                                         FPT->getArgTypes(), EPI)); | 
| Richard Smith | dd25e80 | 2012-07-30 23:48:14 +0000 | [diff] [blame] | 4606 | } | 
 | 4607 |  | 
| Reid Kleckner | ef07203 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 4608 | static FunctionProtoType::ExtProtoInfo getImplicitMethodEPI(Sema &S, | 
 | 4609 |                                                             CXXMethodDecl *MD) { | 
 | 4610 |   FunctionProtoType::ExtProtoInfo EPI; | 
 | 4611 |  | 
 | 4612 |   // Build an exception specification pointing back at this member. | 
 | 4613 |   EPI.ExceptionSpecType = EST_Unevaluated; | 
 | 4614 |   EPI.ExceptionSpecDecl = MD; | 
 | 4615 |  | 
 | 4616 |   // Set the calling convention to the default for C++ instance methods. | 
 | 4617 |   EPI.ExtInfo = EPI.ExtInfo.withCallingConv( | 
 | 4618 |       S.Context.getDefaultCallingConvention(/*IsVariadic=*/false, | 
 | 4619 |                                             /*IsCXXMethod=*/true)); | 
 | 4620 |   return EPI; | 
 | 4621 | } | 
 | 4622 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 4623 | void Sema::EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD) { | 
 | 4624 |   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); | 
 | 4625 |   if (FPT->getExceptionSpecType() != EST_Unevaluated) | 
 | 4626 |     return; | 
 | 4627 |  | 
| Richard Smith | dd25e80 | 2012-07-30 23:48:14 +0000 | [diff] [blame] | 4628 |   // Evaluate the exception specification. | 
 | 4629 |   ImplicitExceptionSpecification ExceptSpec = | 
 | 4630 |       computeImplicitExceptionSpec(*this, Loc, MD); | 
 | 4631 |  | 
 | 4632 |   // Update the type of the special member to use it. | 
 | 4633 |   updateExceptionSpec(*this, MD, FPT, ExceptSpec); | 
 | 4634 |  | 
 | 4635 |   // A user-provided destructor can be defined outside the class. When that | 
 | 4636 |   // happens, be sure to update the exception specification on both | 
 | 4637 |   // declarations. | 
 | 4638 |   const FunctionProtoType *CanonicalFPT = | 
 | 4639 |     MD->getCanonicalDecl()->getType()->castAs<FunctionProtoType>(); | 
 | 4640 |   if (CanonicalFPT->getExceptionSpecType() == EST_Unevaluated) | 
 | 4641 |     updateExceptionSpec(*this, MD->getCanonicalDecl(), | 
 | 4642 |                         CanonicalFPT, ExceptSpec); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 4643 | } | 
 | 4644 |  | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4645 | void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) { | 
 | 4646 |   CXXRecordDecl *RD = MD->getParent(); | 
 | 4647 |   CXXSpecialMember CSM = getSpecialMember(MD); | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 4648 |  | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4649 |   assert(MD->isExplicitlyDefaulted() && CSM != CXXInvalid && | 
 | 4650 |          "not an explicitly-defaulted special member"); | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 4651 |  | 
 | 4652 |   // Whether this was the first-declared instance of the constructor. | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4653 |   // This affects whether we implicitly add an exception spec and constexpr. | 
| Sean Hunt | 2b18808 | 2011-05-14 05:23:28 +0000 | [diff] [blame] | 4654 |   bool First = MD == MD->getCanonicalDecl(); | 
 | 4655 |  | 
 | 4656 |   bool HadError = false; | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4657 |  | 
 | 4658 |   // C++11 [dcl.fct.def.default]p1: | 
 | 4659 |   //   A function that is explicitly defaulted shall | 
 | 4660 |   //     -- be a special member function (checked elsewhere), | 
 | 4661 |   //     -- have the same type (except for ref-qualifiers, and except that a | 
 | 4662 |   //        copy operation can take a non-const reference) as an implicit | 
 | 4663 |   //        declaration, and | 
 | 4664 |   //     -- not have default arguments. | 
 | 4665 |   unsigned ExpectedParams = 1; | 
 | 4666 |   if (CSM == CXXDefaultConstructor || CSM == CXXDestructor) | 
 | 4667 |     ExpectedParams = 0; | 
 | 4668 |   if (MD->getNumParams() != ExpectedParams) { | 
 | 4669 |     // This also checks for default arguments: a copy or move constructor with a | 
 | 4670 |     // default argument is classified as a default constructor, and assignment | 
 | 4671 |     // operations and destructors can't have default arguments. | 
 | 4672 |     Diag(MD->getLocation(), diag::err_defaulted_special_member_params) | 
 | 4673 |       << CSM << MD->getSourceRange(); | 
| Sean Hunt | 2b18808 | 2011-05-14 05:23:28 +0000 | [diff] [blame] | 4674 |     HadError = true; | 
| Richard Smith | 5046439 | 2012-12-07 02:10:28 +0000 | [diff] [blame] | 4675 |   } else if (MD->isVariadic()) { | 
 | 4676 |     Diag(MD->getLocation(), diag::err_defaulted_special_member_variadic) | 
 | 4677 |       << CSM << MD->getSourceRange(); | 
 | 4678 |     HadError = true; | 
| Sean Hunt | 2b18808 | 2011-05-14 05:23:28 +0000 | [diff] [blame] | 4679 |   } | 
 | 4680 |  | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4681 |   const FunctionProtoType *Type = MD->getType()->getAs<FunctionProtoType>(); | 
| Sean Hunt | 2b18808 | 2011-05-14 05:23:28 +0000 | [diff] [blame] | 4682 |  | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4683 |   bool CanHaveConstParam = false; | 
| Richard Smith | ac71351 | 2012-12-08 02:53:02 +0000 | [diff] [blame] | 4684 |   if (CSM == CXXCopyConstructor) | 
| Richard Smith | acf796b | 2012-11-28 06:23:12 +0000 | [diff] [blame] | 4685 |     CanHaveConstParam = RD->implicitCopyConstructorHasConstParam(); | 
| Richard Smith | ac71351 | 2012-12-08 02:53:02 +0000 | [diff] [blame] | 4686 |   else if (CSM == CXXCopyAssignment) | 
| Richard Smith | acf796b | 2012-11-28 06:23:12 +0000 | [diff] [blame] | 4687 |     CanHaveConstParam = RD->implicitCopyAssignmentHasConstParam(); | 
| Sean Hunt | 2b18808 | 2011-05-14 05:23:28 +0000 | [diff] [blame] | 4688 |  | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4689 |   QualType ReturnType = Context.VoidTy; | 
 | 4690 |   if (CSM == CXXCopyAssignment || CSM == CXXMoveAssignment) { | 
 | 4691 |     // Check for return type matching. | 
 | 4692 |     ReturnType = Type->getResultType(); | 
 | 4693 |     QualType ExpectedReturnType = | 
 | 4694 |         Context.getLValueReferenceType(Context.getTypeDeclType(RD)); | 
 | 4695 |     if (!Context.hasSameType(ReturnType, ExpectedReturnType)) { | 
 | 4696 |       Diag(MD->getLocation(), diag::err_defaulted_special_member_return_type) | 
 | 4697 |         << (CSM == CXXMoveAssignment) << ExpectedReturnType; | 
 | 4698 |       HadError = true; | 
 | 4699 |     } | 
 | 4700 |  | 
 | 4701 |     // A defaulted special member cannot have cv-qualifiers. | 
 | 4702 |     if (Type->getTypeQuals()) { | 
 | 4703 |       Diag(MD->getLocation(), diag::err_defaulted_special_member_quals) | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4704 |         << (CSM == CXXMoveAssignment) << getLangOpts().CPlusPlus1y; | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4705 |       HadError = true; | 
 | 4706 |     } | 
 | 4707 |   } | 
 | 4708 |  | 
 | 4709 |   // Check for parameter type matching. | 
 | 4710 |   QualType ArgType = ExpectedParams ? Type->getArgType(0) : QualType(); | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4711 |   bool HasConstParam = false; | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4712 |   if (ExpectedParams && ArgType->isReferenceType()) { | 
 | 4713 |     // Argument must be reference to possibly-const T. | 
 | 4714 |     QualType ReferentType = ArgType->getPointeeType(); | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4715 |     HasConstParam = ReferentType.isConstQualified(); | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4716 |  | 
 | 4717 |     if (ReferentType.isVolatileQualified()) { | 
 | 4718 |       Diag(MD->getLocation(), | 
 | 4719 |            diag::err_defaulted_special_member_volatile_param) << CSM; | 
 | 4720 |       HadError = true; | 
 | 4721 |     } | 
 | 4722 |  | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4723 |     if (HasConstParam && !CanHaveConstParam) { | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4724 |       if (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment) { | 
 | 4725 |         Diag(MD->getLocation(), | 
 | 4726 |              diag::err_defaulted_special_member_copy_const_param) | 
 | 4727 |           << (CSM == CXXCopyAssignment); | 
 | 4728 |         // FIXME: Explain why this special member can't be const. | 
 | 4729 |       } else { | 
 | 4730 |         Diag(MD->getLocation(), | 
 | 4731 |              diag::err_defaulted_special_member_move_const_param) | 
 | 4732 |           << (CSM == CXXMoveAssignment); | 
 | 4733 |       } | 
 | 4734 |       HadError = true; | 
 | 4735 |     } | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4736 |   } else if (ExpectedParams) { | 
 | 4737 |     // A copy assignment operator can take its argument by value, but a | 
 | 4738 |     // defaulted one cannot. | 
 | 4739 |     assert(CSM == CXXCopyAssignment && "unexpected non-ref argument"); | 
| Sean Hunt | be63122 | 2011-05-17 20:44:43 +0000 | [diff] [blame] | 4740 |     Diag(MD->getLocation(), diag::err_defaulted_copy_assign_not_ref); | 
| Sean Hunt | 2b18808 | 2011-05-14 05:23:28 +0000 | [diff] [blame] | 4741 |     HadError = true; | 
 | 4742 |   } | 
| Sean Hunt | be63122 | 2011-05-17 20:44:43 +0000 | [diff] [blame] | 4743 |  | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 4744 |   // C++11 [dcl.fct.def.default]p2: | 
 | 4745 |   //   An explicitly-defaulted function may be declared constexpr only if it | 
 | 4746 |   //   would have been implicitly declared as constexpr, | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4747 |   // Do not apply this rule to members of class templates, since core issue 1358 | 
 | 4748 |   // makes such functions always instantiate to constexpr functions. For | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4749 |   // functions which cannot be constexpr (for non-constructors in C++11 and for | 
 | 4750 |   // destructors in C++1y), this is checked elsewhere. | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 4751 |   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, RD, CSM, | 
 | 4752 |                                                      HasConstParam); | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4753 |   if ((getLangOpts().CPlusPlus1y ? !isa<CXXDestructorDecl>(MD) | 
 | 4754 |                                  : isa<CXXConstructorDecl>(MD)) && | 
 | 4755 |       MD->isConstexpr() && !Constexpr && | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4756 |       MD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) { | 
 | 4757 |     Diag(MD->getLocStart(), diag::err_incorrect_defaulted_constexpr) << CSM; | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 4758 |     // FIXME: Explain why the special member can't be constexpr. | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4759 |     HadError = true; | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 4760 |   } | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4761 |  | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 4762 |   //   and may have an explicit exception-specification only if it is compatible | 
 | 4763 |   //   with the exception-specification on the implicit declaration. | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4764 |   if (Type->hasExceptionSpec()) { | 
 | 4765 |     // Delay the check if this is the first declaration of the special member, | 
 | 4766 |     // since we may not have parsed some necessary in-class initializers yet. | 
| Richard Smith | 12fef49 | 2013-03-27 00:22:47 +0000 | [diff] [blame] | 4767 |     if (First) { | 
 | 4768 |       // If the exception specification needs to be instantiated, do so now, | 
 | 4769 |       // before we clobber it with an EST_Unevaluated specification below. | 
 | 4770 |       if (Type->getExceptionSpecType() == EST_Uninstantiated) { | 
 | 4771 |         InstantiateExceptionSpec(MD->getLocStart(), MD); | 
 | 4772 |         Type = MD->getType()->getAs<FunctionProtoType>(); | 
 | 4773 |       } | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4774 |       DelayedDefaultedMemberExceptionSpecs.push_back(std::make_pair(MD, Type)); | 
| Richard Smith | 12fef49 | 2013-03-27 00:22:47 +0000 | [diff] [blame] | 4775 |     } else | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4776 |       CheckExplicitlyDefaultedMemberExceptionSpec(MD, Type); | 
 | 4777 |   } | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 4778 |  | 
 | 4779 |   //   If a function is explicitly defaulted on its first declaration, | 
 | 4780 |   if (First) { | 
 | 4781 |     //  -- it is implicitly considered to be constexpr if the implicit | 
 | 4782 |     //     definition would be, | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4783 |     MD->setConstexpr(Constexpr); | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 4784 |  | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4785 |     //  -- it is implicitly considered to have the same exception-specification | 
 | 4786 |     //     as if it had been implicitly declared, | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4787 |     FunctionProtoType::ExtProtoInfo EPI = Type->getExtProtoInfo(); | 
 | 4788 |     EPI.ExceptionSpecType = EST_Unevaluated; | 
 | 4789 |     EPI.ExceptionSpecDecl = MD; | 
| Jordan Rose | bea522f | 2013-03-08 21:51:21 +0000 | [diff] [blame] | 4790 |     MD->setType(Context.getFunctionType(ReturnType, | 
 | 4791 |                                         ArrayRef<QualType>(&ArgType, | 
 | 4792 |                                                            ExpectedParams), | 
 | 4793 |                                         EPI)); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 4794 |   } | 
 | 4795 |  | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4796 |   if (ShouldDeleteSpecialMember(MD, CSM)) { | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 4797 |     if (First) { | 
| Richard Smith | 0ab5b4c | 2013-04-02 19:38:47 +0000 | [diff] [blame] | 4798 |       SetDeclDeleted(MD, MD->getLocation()); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 4799 |     } else { | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4800 |       // C++11 [dcl.fct.def.default]p4: | 
 | 4801 |       //   [For a] user-provided explicitly-defaulted function [...] if such a | 
 | 4802 |       //   function is implicitly defined as deleted, the program is ill-formed. | 
 | 4803 |       Diag(MD->getLocation(), diag::err_out_of_line_default_deletes) << CSM; | 
 | 4804 |       HadError = true; | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 4805 |     } | 
 | 4806 |   } | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 4807 |  | 
| Richard Smith | 3003e1d | 2012-05-15 04:39:51 +0000 | [diff] [blame] | 4808 |   if (HadError) | 
 | 4809 |     MD->setInvalidDecl(); | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 4810 | } | 
 | 4811 |  | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4812 | /// Check whether the exception specification provided for an | 
 | 4813 | /// explicitly-defaulted special member matches the exception specification | 
 | 4814 | /// that would have been generated for an implicit special member, per | 
 | 4815 | /// C++11 [dcl.fct.def.default]p2. | 
 | 4816 | void Sema::CheckExplicitlyDefaultedMemberExceptionSpec( | 
 | 4817 |     CXXMethodDecl *MD, const FunctionProtoType *SpecifiedType) { | 
 | 4818 |   // Compute the implicit exception specification. | 
| Reid Kleckner | ef07203 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 4819 |   CallingConv CC = Context.getDefaultCallingConvention(/*IsVariadic=*/false, | 
 | 4820 |                                                        /*IsCXXMethod=*/true); | 
 | 4821 |   FunctionProtoType::ExtProtoInfo EPI(CC); | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4822 |   computeImplicitExceptionSpec(*this, MD->getLocation(), MD).getEPI(EPI); | 
 | 4823 |   const FunctionProtoType *ImplicitType = cast<FunctionProtoType>( | 
| Dmitri Gribenko | 5543169 | 2013-05-05 00:41:58 +0000 | [diff] [blame] | 4824 |     Context.getFunctionType(Context.VoidTy, None, EPI)); | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 4825 |  | 
 | 4826 |   // Ensure that it matches. | 
 | 4827 |   CheckEquivalentExceptionSpec( | 
 | 4828 |     PDiag(diag::err_incorrect_defaulted_exception_spec) | 
 | 4829 |       << getSpecialMember(MD), PDiag(), | 
 | 4830 |     ImplicitType, SourceLocation(), | 
 | 4831 |     SpecifiedType, MD->getLocation()); | 
 | 4832 | } | 
 | 4833 |  | 
 | 4834 | void Sema::CheckDelayedExplicitlyDefaultedMemberExceptionSpecs() { | 
 | 4835 |   for (unsigned I = 0, N = DelayedDefaultedMemberExceptionSpecs.size(); | 
 | 4836 |        I != N; ++I) | 
 | 4837 |     CheckExplicitlyDefaultedMemberExceptionSpec( | 
 | 4838 |       DelayedDefaultedMemberExceptionSpecs[I].first, | 
 | 4839 |       DelayedDefaultedMemberExceptionSpecs[I].second); | 
 | 4840 |  | 
 | 4841 |   DelayedDefaultedMemberExceptionSpecs.clear(); | 
 | 4842 | } | 
 | 4843 |  | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 4844 | namespace { | 
 | 4845 | struct SpecialMemberDeletionInfo { | 
 | 4846 |   Sema &S; | 
 | 4847 |   CXXMethodDecl *MD; | 
 | 4848 |   Sema::CXXSpecialMember CSM; | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 4849 |   bool Diagnose; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 4850 |  | 
 | 4851 |   // Properties of the special member, computed for convenience. | 
 | 4852 |   bool IsConstructor, IsAssignment, IsMove, ConstArg, VolatileArg; | 
 | 4853 |   SourceLocation Loc; | 
 | 4854 |  | 
 | 4855 |   bool AllFieldsAreConst; | 
 | 4856 |  | 
 | 4857 |   SpecialMemberDeletionInfo(Sema &S, CXXMethodDecl *MD, | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 4858 |                             Sema::CXXSpecialMember CSM, bool Diagnose) | 
 | 4859 |     : S(S), MD(MD), CSM(CSM), Diagnose(Diagnose), | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 4860 |       IsConstructor(false), IsAssignment(false), IsMove(false), | 
 | 4861 |       ConstArg(false), VolatileArg(false), Loc(MD->getLocation()), | 
 | 4862 |       AllFieldsAreConst(true) { | 
 | 4863 |     switch (CSM) { | 
 | 4864 |       case Sema::CXXDefaultConstructor: | 
 | 4865 |       case Sema::CXXCopyConstructor: | 
 | 4866 |         IsConstructor = true; | 
 | 4867 |         break; | 
 | 4868 |       case Sema::CXXMoveConstructor: | 
 | 4869 |         IsConstructor = true; | 
 | 4870 |         IsMove = true; | 
 | 4871 |         break; | 
 | 4872 |       case Sema::CXXCopyAssignment: | 
 | 4873 |         IsAssignment = true; | 
 | 4874 |         break; | 
 | 4875 |       case Sema::CXXMoveAssignment: | 
 | 4876 |         IsAssignment = true; | 
 | 4877 |         IsMove = true; | 
 | 4878 |         break; | 
 | 4879 |       case Sema::CXXDestructor: | 
 | 4880 |         break; | 
 | 4881 |       case Sema::CXXInvalid: | 
 | 4882 |         llvm_unreachable("invalid special member kind"); | 
 | 4883 |     } | 
 | 4884 |  | 
 | 4885 |     if (MD->getNumParams()) { | 
 | 4886 |       ConstArg = MD->getParamDecl(0)->getType().isConstQualified(); | 
 | 4887 |       VolatileArg = MD->getParamDecl(0)->getType().isVolatileQualified(); | 
 | 4888 |     } | 
 | 4889 |   } | 
 | 4890 |  | 
 | 4891 |   bool inUnion() const { return MD->getParent()->isUnion(); } | 
 | 4892 |  | 
 | 4893 |   /// Look up the corresponding special member in the given class. | 
| Richard Smith | 517bb84 | 2012-07-18 03:51:16 +0000 | [diff] [blame] | 4894 |   Sema::SpecialMemberOverloadResult *lookupIn(CXXRecordDecl *Class, | 
 | 4895 |                                               unsigned Quals) { | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 4896 |     unsigned TQ = MD->getTypeQualifiers(); | 
| Richard Smith | 517bb84 | 2012-07-18 03:51:16 +0000 | [diff] [blame] | 4897 |     // cv-qualifiers on class members don't affect default ctor / dtor calls. | 
 | 4898 |     if (CSM == Sema::CXXDefaultConstructor || CSM == Sema::CXXDestructor) | 
 | 4899 |       Quals = 0; | 
 | 4900 |     return S.LookupSpecialMember(Class, CSM, | 
 | 4901 |                                  ConstArg || (Quals & Qualifiers::Const), | 
 | 4902 |                                  VolatileArg || (Quals & Qualifiers::Volatile), | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 4903 |                                  MD->getRefQualifier() == RQ_RValue, | 
 | 4904 |                                  TQ & Qualifiers::Const, | 
 | 4905 |                                  TQ & Qualifiers::Volatile); | 
 | 4906 |   } | 
 | 4907 |  | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 4908 |   typedef llvm::PointerUnion<CXXBaseSpecifier*, FieldDecl*> Subobject; | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 4909 |  | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 4910 |   bool shouldDeleteForBase(CXXBaseSpecifier *Base); | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 4911 |   bool shouldDeleteForField(FieldDecl *FD); | 
 | 4912 |   bool shouldDeleteForAllConstMembers(); | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 4913 |  | 
| Richard Smith | 517bb84 | 2012-07-18 03:51:16 +0000 | [diff] [blame] | 4914 |   bool shouldDeleteForClassSubobject(CXXRecordDecl *Class, Subobject Subobj, | 
 | 4915 |                                      unsigned Quals); | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 4916 |   bool shouldDeleteForSubobjectCall(Subobject Subobj, | 
 | 4917 |                                     Sema::SpecialMemberOverloadResult *SMOR, | 
 | 4918 |                                     bool IsDtorCallInCtor); | 
| John McCall | 12d8d80 | 2012-04-09 20:53:23 +0000 | [diff] [blame] | 4919 |  | 
 | 4920 |   bool isAccessible(Subobject Subobj, CXXMethodDecl *D); | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 4921 | }; | 
 | 4922 | } | 
 | 4923 |  | 
| John McCall | 12d8d80 | 2012-04-09 20:53:23 +0000 | [diff] [blame] | 4924 | /// Is the given special member inaccessible when used on the given | 
 | 4925 | /// sub-object. | 
 | 4926 | bool SpecialMemberDeletionInfo::isAccessible(Subobject Subobj, | 
 | 4927 |                                              CXXMethodDecl *target) { | 
 | 4928 |   /// If we're operating on a base class, the object type is the | 
 | 4929 |   /// type of this special member. | 
 | 4930 |   QualType objectTy; | 
| Dmitri Gribenko | 1ad23d6 | 2012-09-10 21:20:09 +0000 | [diff] [blame] | 4931 |   AccessSpecifier access = target->getAccess(); | 
| John McCall | 12d8d80 | 2012-04-09 20:53:23 +0000 | [diff] [blame] | 4932 |   if (CXXBaseSpecifier *base = Subobj.dyn_cast<CXXBaseSpecifier*>()) { | 
 | 4933 |     objectTy = S.Context.getTypeDeclType(MD->getParent()); | 
 | 4934 |     access = CXXRecordDecl::MergeAccess(base->getAccessSpecifier(), access); | 
 | 4935 |  | 
 | 4936 |   // If we're operating on a field, the object type is the type of the field. | 
 | 4937 |   } else { | 
 | 4938 |     objectTy = S.Context.getTypeDeclType(target->getParent()); | 
 | 4939 |   } | 
 | 4940 |  | 
 | 4941 |   return S.isSpecialMemberAccessibleForDeletion(target, access, objectTy); | 
 | 4942 | } | 
 | 4943 |  | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 4944 | /// Check whether we should delete a special member due to the implicit | 
 | 4945 | /// definition containing a call to a special member of a subobject. | 
 | 4946 | bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall( | 
 | 4947 |     Subobject Subobj, Sema::SpecialMemberOverloadResult *SMOR, | 
 | 4948 |     bool IsDtorCallInCtor) { | 
 | 4949 |   CXXMethodDecl *Decl = SMOR->getMethod(); | 
 | 4950 |   FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>(); | 
 | 4951 |  | 
 | 4952 |   int DiagKind = -1; | 
 | 4953 |  | 
 | 4954 |   if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted) | 
 | 4955 |     DiagKind = !Decl ? 0 : 1; | 
 | 4956 |   else if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::Ambiguous) | 
 | 4957 |     DiagKind = 2; | 
| John McCall | 12d8d80 | 2012-04-09 20:53:23 +0000 | [diff] [blame] | 4958 |   else if (!isAccessible(Subobj, Decl)) | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 4959 |     DiagKind = 3; | 
 | 4960 |   else if (!IsDtorCallInCtor && Field && Field->getParent()->isUnion() && | 
 | 4961 |            !Decl->isTrivial()) { | 
 | 4962 |     // A member of a union must have a trivial corresponding special member. | 
 | 4963 |     // As a weird special case, a destructor call from a union's constructor | 
 | 4964 |     // must be accessible and non-deleted, but need not be trivial. Such a | 
 | 4965 |     // destructor is never actually called, but is semantically checked as | 
 | 4966 |     // if it were. | 
 | 4967 |     DiagKind = 4; | 
 | 4968 |   } | 
 | 4969 |  | 
 | 4970 |   if (DiagKind == -1) | 
 | 4971 |     return false; | 
 | 4972 |  | 
 | 4973 |   if (Diagnose) { | 
 | 4974 |     if (Field) { | 
 | 4975 |       S.Diag(Field->getLocation(), | 
 | 4976 |              diag::note_deleted_special_member_class_subobject) | 
 | 4977 |         << CSM << MD->getParent() << /*IsField*/true | 
 | 4978 |         << Field << DiagKind << IsDtorCallInCtor; | 
 | 4979 |     } else { | 
 | 4980 |       CXXBaseSpecifier *Base = Subobj.get<CXXBaseSpecifier*>(); | 
 | 4981 |       S.Diag(Base->getLocStart(), | 
 | 4982 |              diag::note_deleted_special_member_class_subobject) | 
 | 4983 |         << CSM << MD->getParent() << /*IsField*/false | 
 | 4984 |         << Base->getType() << DiagKind << IsDtorCallInCtor; | 
 | 4985 |     } | 
 | 4986 |  | 
 | 4987 |     if (DiagKind == 1) | 
 | 4988 |       S.NoteDeletedFunction(Decl); | 
 | 4989 |     // FIXME: Explain inaccessibility if DiagKind == 3. | 
 | 4990 |   } | 
 | 4991 |  | 
 | 4992 |   return true; | 
 | 4993 | } | 
 | 4994 |  | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 4995 | /// Check whether we should delete a special member function due to having a | 
| Richard Smith | 517bb84 | 2012-07-18 03:51:16 +0000 | [diff] [blame] | 4996 | /// direct or virtual base class or non-static data member of class type M. | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 4997 | bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject( | 
| Richard Smith | 517bb84 | 2012-07-18 03:51:16 +0000 | [diff] [blame] | 4998 |     CXXRecordDecl *Class, Subobject Subobj, unsigned Quals) { | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 4999 |   FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>(); | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5000 |  | 
 | 5001 |   // C++11 [class.ctor]p5: | 
| Richard Smith | df8dc86 | 2012-03-29 19:00:10 +0000 | [diff] [blame] | 5002 |   // -- any direct or virtual base class, or non-static data member with no | 
 | 5003 |   //    brace-or-equal-initializer, has class type M (or array thereof) and | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5004 |   //    either M has no default constructor or overload resolution as applied | 
 | 5005 |   //    to M's default constructor results in an ambiguity or in a function | 
 | 5006 |   //    that is deleted or inaccessible | 
 | 5007 |   // C++11 [class.copy]p11, C++11 [class.copy]p23: | 
 | 5008 |   // -- a direct or virtual base class B that cannot be copied/moved because | 
 | 5009 |   //    overload resolution, as applied to B's corresponding special member, | 
 | 5010 |   //    results in an ambiguity or a function that is deleted or inaccessible | 
 | 5011 |   //    from the defaulted special member | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5012 |   // C++11 [class.dtor]p5: | 
 | 5013 |   // -- any direct or virtual base class [...] has a type with a destructor | 
 | 5014 |   //    that is deleted or inaccessible | 
 | 5015 |   if (!(CSM == Sema::CXXDefaultConstructor && | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 5016 |         Field && Field->hasInClassInitializer()) && | 
| Richard Smith | 517bb84 | 2012-07-18 03:51:16 +0000 | [diff] [blame] | 5017 |       shouldDeleteForSubobjectCall(Subobj, lookupIn(Class, Quals), false)) | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 5018 |     return true; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5019 |  | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5020 |   // C++11 [class.ctor]p5, C++11 [class.copy]p11: | 
 | 5021 |   // -- any direct or virtual base class or non-static data member has a | 
 | 5022 |   //    type with a destructor that is deleted or inaccessible | 
 | 5023 |   if (IsConstructor) { | 
 | 5024 |     Sema::SpecialMemberOverloadResult *SMOR = | 
 | 5025 |         S.LookupSpecialMember(Class, Sema::CXXDestructor, | 
 | 5026 |                               false, false, false, false, false); | 
 | 5027 |     if (shouldDeleteForSubobjectCall(Subobj, SMOR, true)) | 
 | 5028 |       return true; | 
 | 5029 |   } | 
 | 5030 |  | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 5031 |   return false; | 
 | 5032 | } | 
 | 5033 |  | 
 | 5034 | /// Check whether we should delete a special member function due to the class | 
 | 5035 | /// having a particular direct or virtual base class. | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5036 | bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXBaseSpecifier *Base) { | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 5037 |   CXXRecordDecl *BaseClass = Base->getType()->getAsCXXRecordDecl(); | 
| Richard Smith | 517bb84 | 2012-07-18 03:51:16 +0000 | [diff] [blame] | 5038 |   return shouldDeleteForClassSubobject(BaseClass, Base, 0); | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5039 | } | 
 | 5040 |  | 
 | 5041 | /// Check whether we should delete a special member function due to the class | 
 | 5042 | /// having a particular non-static data member. | 
 | 5043 | bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) { | 
 | 5044 |   QualType FieldType = S.Context.getBaseElementType(FD->getType()); | 
 | 5045 |   CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl(); | 
 | 5046 |  | 
 | 5047 |   if (CSM == Sema::CXXDefaultConstructor) { | 
 | 5048 |     // For a default constructor, all references must be initialized in-class | 
 | 5049 |     // and, if a union, it must have a non-const member. | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5050 |     if (FieldType->isReferenceType() && !FD->hasInClassInitializer()) { | 
 | 5051 |       if (Diagnose) | 
 | 5052 |         S.Diag(FD->getLocation(), diag::note_deleted_default_ctor_uninit_field) | 
 | 5053 |           << MD->getParent() << FD << FieldType << /*Reference*/0; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5054 |       return true; | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5055 |     } | 
| Richard Smith | 79363f5 | 2012-02-27 06:07:25 +0000 | [diff] [blame] | 5056 |     // C++11 [class.ctor]p5: any non-variant non-static data member of | 
 | 5057 |     // const-qualified type (or array thereof) with no | 
 | 5058 |     // brace-or-equal-initializer does not have a user-provided default | 
 | 5059 |     // constructor. | 
 | 5060 |     if (!inUnion() && FieldType.isConstQualified() && | 
 | 5061 |         !FD->hasInClassInitializer() && | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5062 |         (!FieldRecord || !FieldRecord->hasUserProvidedDefaultConstructor())) { | 
 | 5063 |       if (Diagnose) | 
 | 5064 |         S.Diag(FD->getLocation(), diag::note_deleted_default_ctor_uninit_field) | 
| Richard Smith | a2e76f5 | 2012-04-29 06:32:34 +0000 | [diff] [blame] | 5065 |           << MD->getParent() << FD << FD->getType() << /*Const*/1; | 
| Richard Smith | 79363f5 | 2012-02-27 06:07:25 +0000 | [diff] [blame] | 5066 |       return true; | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5067 |     } | 
 | 5068 |  | 
 | 5069 |     if (inUnion() && !FieldType.isConstQualified()) | 
 | 5070 |       AllFieldsAreConst = false; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5071 |   } else if (CSM == Sema::CXXCopyConstructor) { | 
 | 5072 |     // For a copy constructor, data members must not be of rvalue reference | 
 | 5073 |     // type. | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5074 |     if (FieldType->isRValueReferenceType()) { | 
 | 5075 |       if (Diagnose) | 
 | 5076 |         S.Diag(FD->getLocation(), diag::note_deleted_copy_ctor_rvalue_reference) | 
 | 5077 |           << MD->getParent() << FD << FieldType; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5078 |       return true; | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5079 |     } | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5080 |   } else if (IsAssignment) { | 
 | 5081 |     // For an assignment operator, data members must not be of reference type. | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5082 |     if (FieldType->isReferenceType()) { | 
 | 5083 |       if (Diagnose) | 
 | 5084 |         S.Diag(FD->getLocation(), diag::note_deleted_assign_field) | 
 | 5085 |           << IsMove << MD->getParent() << FD << FieldType << /*Reference*/0; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5086 |       return true; | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5087 |     } | 
 | 5088 |     if (!FieldRecord && FieldType.isConstQualified()) { | 
 | 5089 |       // C++11 [class.copy]p23: | 
 | 5090 |       // -- a non-static data member of const non-class type (or array thereof) | 
 | 5091 |       if (Diagnose) | 
 | 5092 |         S.Diag(FD->getLocation(), diag::note_deleted_assign_field) | 
| Richard Smith | a2e76f5 | 2012-04-29 06:32:34 +0000 | [diff] [blame] | 5093 |           << IsMove << MD->getParent() << FD << FD->getType() << /*Const*/1; | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5094 |       return true; | 
 | 5095 |     } | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5096 |   } | 
 | 5097 |  | 
 | 5098 |   if (FieldRecord) { | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5099 |     // Some additional restrictions exist on the variant members. | 
 | 5100 |     if (!inUnion() && FieldRecord->isUnion() && | 
 | 5101 |         FieldRecord->isAnonymousStructOrUnion()) { | 
 | 5102 |       bool AllVariantFieldsAreConst = true; | 
 | 5103 |  | 
| Richard Smith | df8dc86 | 2012-03-29 19:00:10 +0000 | [diff] [blame] | 5104 |       // FIXME: Handle anonymous unions declared within anonymous unions. | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5105 |       for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(), | 
 | 5106 |                                          UE = FieldRecord->field_end(); | 
 | 5107 |            UI != UE; ++UI) { | 
 | 5108 |         QualType UnionFieldType = S.Context.getBaseElementType(UI->getType()); | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5109 |  | 
 | 5110 |         if (!UnionFieldType.isConstQualified()) | 
 | 5111 |           AllVariantFieldsAreConst = false; | 
 | 5112 |  | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 5113 |         CXXRecordDecl *UnionFieldRecord = UnionFieldType->getAsCXXRecordDecl(); | 
 | 5114 |         if (UnionFieldRecord && | 
| Richard Smith | 517bb84 | 2012-07-18 03:51:16 +0000 | [diff] [blame] | 5115 |             shouldDeleteForClassSubobject(UnionFieldRecord, *UI, | 
 | 5116 |                                           UnionFieldType.getCVRQualifiers())) | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 5117 |           return true; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5118 |       } | 
 | 5119 |  | 
 | 5120 |       // At least one member in each anonymous union must be non-const | 
| Douglas Gregor | 221c27f | 2012-02-24 21:25:53 +0000 | [diff] [blame] | 5121 |       if (CSM == Sema::CXXDefaultConstructor && AllVariantFieldsAreConst && | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5122 |           FieldRecord->field_begin() != FieldRecord->field_end()) { | 
 | 5123 |         if (Diagnose) | 
 | 5124 |           S.Diag(FieldRecord->getLocation(), | 
 | 5125 |                  diag::note_deleted_default_ctor_all_const) | 
 | 5126 |             << MD->getParent() << /*anonymous union*/1; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5127 |         return true; | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5128 |       } | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5129 |  | 
| Richard Smith | df8dc86 | 2012-03-29 19:00:10 +0000 | [diff] [blame] | 5130 |       // Don't check the implicit member of the anonymous union type. | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5131 |       // This is technically non-conformant, but sanity demands it. | 
 | 5132 |       return false; | 
 | 5133 |     } | 
 | 5134 |  | 
| Richard Smith | 517bb84 | 2012-07-18 03:51:16 +0000 | [diff] [blame] | 5135 |     if (shouldDeleteForClassSubobject(FieldRecord, FD, | 
 | 5136 |                                       FieldType.getCVRQualifiers())) | 
| Richard Smith | df8dc86 | 2012-03-29 19:00:10 +0000 | [diff] [blame] | 5137 |       return true; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5138 |   } | 
 | 5139 |  | 
 | 5140 |   return false; | 
 | 5141 | } | 
 | 5142 |  | 
 | 5143 | /// C++11 [class.ctor] p5: | 
 | 5144 | ///   A defaulted default constructor for a class X is defined as deleted if | 
 | 5145 | /// X is a union and all of its variant members are of const-qualified type. | 
 | 5146 | bool SpecialMemberDeletionInfo::shouldDeleteForAllConstMembers() { | 
| Douglas Gregor | 221c27f | 2012-02-24 21:25:53 +0000 | [diff] [blame] | 5147 |   // This is a silly definition, because it gives an empty union a deleted | 
 | 5148 |   // default constructor. Don't do that. | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5149 |   if (CSM == Sema::CXXDefaultConstructor && inUnion() && AllFieldsAreConst && | 
 | 5150 |       (MD->getParent()->field_begin() != MD->getParent()->field_end())) { | 
 | 5151 |     if (Diagnose) | 
 | 5152 |       S.Diag(MD->getParent()->getLocation(), | 
 | 5153 |              diag::note_deleted_default_ctor_all_const) | 
 | 5154 |         << MD->getParent() << /*not anonymous union*/0; | 
 | 5155 |     return true; | 
 | 5156 |   } | 
 | 5157 |   return false; | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5158 | } | 
 | 5159 |  | 
 | 5160 | /// Determine whether a defaulted special member function should be defined as | 
 | 5161 | /// deleted, as specified in C++11 [class.ctor]p5, C++11 [class.copy]p11, | 
 | 5162 | /// C++11 [class.copy]p23, and C++11 [class.dtor]p5. | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5163 | bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, | 
 | 5164 |                                      bool Diagnose) { | 
| Richard Smith | eef0029 | 2012-08-06 02:25:10 +0000 | [diff] [blame] | 5165 |   if (MD->isInvalidDecl()) | 
 | 5166 |     return false; | 
| Sean Hunt | e16da07 | 2011-10-10 06:18:57 +0000 | [diff] [blame] | 5167 |   CXXRecordDecl *RD = MD->getParent(); | 
| Sean Hunt | cdee3fe | 2011-05-11 22:34:38 +0000 | [diff] [blame] | 5168 |   assert(!RD->isDependentType() && "do deletion after instantiation"); | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 5169 |   if (!LangOpts.CPlusPlus11 || RD->isInvalidDecl()) | 
| Sean Hunt | cdee3fe | 2011-05-11 22:34:38 +0000 | [diff] [blame] | 5170 |     return false; | 
 | 5171 |  | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5172 |   // C++11 [expr.lambda.prim]p19: | 
 | 5173 |   //   The closure type associated with a lambda-expression has a | 
 | 5174 |   //   deleted (8.4.3) default constructor and a deleted copy | 
 | 5175 |   //   assignment operator. | 
 | 5176 |   if (RD->isLambda() && | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5177 |       (CSM == CXXDefaultConstructor || CSM == CXXCopyAssignment)) { | 
 | 5178 |     if (Diagnose) | 
 | 5179 |       Diag(RD->getLocation(), diag::note_lambda_decl); | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5180 |     return true; | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5181 |   } | 
 | 5182 |  | 
| Richard Smith | 5bdaac5 | 2012-04-02 20:59:25 +0000 | [diff] [blame] | 5183 |   // For an anonymous struct or union, the copy and assignment special members | 
 | 5184 |   // will never be used, so skip the check. For an anonymous union declared at | 
 | 5185 |   // namespace scope, the constructor and destructor are used. | 
 | 5186 |   if (CSM != CXXDefaultConstructor && CSM != CXXDestructor && | 
 | 5187 |       RD->isAnonymousStructOrUnion()) | 
 | 5188 |     return false; | 
 | 5189 |  | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5190 |   // C++11 [class.copy]p7, p18: | 
 | 5191 |   //   If the class definition declares a move constructor or move assignment | 
 | 5192 |   //   operator, an implicitly declared copy constructor or copy assignment | 
 | 5193 |   //   operator is defined as deleted. | 
 | 5194 |   if (MD->isImplicit() && | 
 | 5195 |       (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment)) { | 
 | 5196 |     CXXMethodDecl *UserDeclaredMove = 0; | 
 | 5197 |  | 
 | 5198 |     // In Microsoft mode, a user-declared move only causes the deletion of the | 
 | 5199 |     // corresponding copy operation, not both copy operations. | 
 | 5200 |     if (RD->hasUserDeclaredMoveConstructor() && | 
 | 5201 |         (!getLangOpts().MicrosoftMode || CSM == CXXCopyConstructor)) { | 
 | 5202 |       if (!Diagnose) return true; | 
| Richard Smith | 5579865 | 2012-12-08 04:10:18 +0000 | [diff] [blame] | 5203 |  | 
 | 5204 |       // Find any user-declared move constructor. | 
 | 5205 |       for (CXXRecordDecl::ctor_iterator I = RD->ctor_begin(), | 
 | 5206 |                                         E = RD->ctor_end(); I != E; ++I) { | 
 | 5207 |         if (I->isMoveConstructor()) { | 
 | 5208 |           UserDeclaredMove = *I; | 
 | 5209 |           break; | 
 | 5210 |         } | 
 | 5211 |       } | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 5212 |       assert(UserDeclaredMove); | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5213 |     } else if (RD->hasUserDeclaredMoveAssignment() && | 
 | 5214 |                (!getLangOpts().MicrosoftMode || CSM == CXXCopyAssignment)) { | 
 | 5215 |       if (!Diagnose) return true; | 
| Richard Smith | 5579865 | 2012-12-08 04:10:18 +0000 | [diff] [blame] | 5216 |  | 
 | 5217 |       // Find any user-declared move assignment operator. | 
 | 5218 |       for (CXXRecordDecl::method_iterator I = RD->method_begin(), | 
 | 5219 |                                           E = RD->method_end(); I != E; ++I) { | 
 | 5220 |         if (I->isMoveAssignmentOperator()) { | 
 | 5221 |           UserDeclaredMove = *I; | 
 | 5222 |           break; | 
 | 5223 |         } | 
 | 5224 |       } | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 5225 |       assert(UserDeclaredMove); | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5226 |     } | 
 | 5227 |  | 
 | 5228 |     if (UserDeclaredMove) { | 
 | 5229 |       Diag(UserDeclaredMove->getLocation(), | 
 | 5230 |            diag::note_deleted_copy_user_declared_move) | 
| Richard Smith | e6af660 | 2012-04-02 21:07:48 +0000 | [diff] [blame] | 5231 |         << (CSM == CXXCopyAssignment) << RD | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5232 |         << UserDeclaredMove->isMoveAssignmentOperator(); | 
 | 5233 |       return true; | 
 | 5234 |     } | 
 | 5235 |   } | 
| Sean Hunt | e16da07 | 2011-10-10 06:18:57 +0000 | [diff] [blame] | 5236 |  | 
| Richard Smith | 5bdaac5 | 2012-04-02 20:59:25 +0000 | [diff] [blame] | 5237 |   // Do access control from the special member function | 
 | 5238 |   ContextRAII MethodContext(*this, MD); | 
 | 5239 |  | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 5240 |   // C++11 [class.dtor]p5: | 
 | 5241 |   // -- for a virtual destructor, lookup of the non-array deallocation function | 
 | 5242 |   //    results in an ambiguity or in a function that is deleted or inaccessible | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5243 |   if (CSM == CXXDestructor && MD->isVirtual()) { | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 5244 |     FunctionDecl *OperatorDelete = 0; | 
 | 5245 |     DeclarationName Name = | 
 | 5246 |       Context.DeclarationNames.getCXXOperatorName(OO_Delete); | 
 | 5247 |     if (FindDeallocationFunction(MD->getLocation(), MD->getParent(), Name, | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5248 |                                  OperatorDelete, false)) { | 
 | 5249 |       if (Diagnose) | 
 | 5250 |         Diag(RD->getLocation(), diag::note_deleted_dtor_no_operator_delete); | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 5251 |       return true; | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5252 |     } | 
| Richard Smith | 9a561d5 | 2012-02-26 09:11:52 +0000 | [diff] [blame] | 5253 |   } | 
 | 5254 |  | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5255 |   SpecialMemberDeletionInfo SMI(*this, MD, CSM, Diagnose); | 
| Sean Hunt | cdee3fe | 2011-05-11 22:34:38 +0000 | [diff] [blame] | 5256 |  | 
| Sean Hunt | cdee3fe | 2011-05-11 22:34:38 +0000 | [diff] [blame] | 5257 |   for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(), | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5258 |                                           BE = RD->bases_end(); BI != BE; ++BI) | 
 | 5259 |     if (!BI->isVirtual() && | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 5260 |         SMI.shouldDeleteForBase(BI)) | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5261 |       return true; | 
| Sean Hunt | cdee3fe | 2011-05-11 22:34:38 +0000 | [diff] [blame] | 5262 |  | 
| Richard Smith | e088360 | 2013-07-22 18:06:23 +0000 | [diff] [blame] | 5263 |   // Per DR1611, do not consider virtual bases of constructors of abstract | 
 | 5264 |   // classes, since we are not going to construct them. | 
| Richard Smith | cbc820a | 2013-07-22 02:56:56 +0000 | [diff] [blame] | 5265 |   if (!RD->isAbstract() || !SMI.IsConstructor) { | 
 | 5266 |     for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(), | 
 | 5267 |                                             BE = RD->vbases_end(); | 
 | 5268 |          BI != BE; ++BI) | 
 | 5269 |       if (SMI.shouldDeleteForBase(BI)) | 
 | 5270 |         return true; | 
 | 5271 |   } | 
| Sean Hunt | cdee3fe | 2011-05-11 22:34:38 +0000 | [diff] [blame] | 5272 |  | 
 | 5273 |   for (CXXRecordDecl::field_iterator FI = RD->field_begin(), | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5274 |                                      FE = RD->field_end(); FI != FE; ++FI) | 
 | 5275 |     if (!FI->isInvalidDecl() && !FI->isUnnamedBitfield() && | 
| David Blaikie | 581deb3 | 2012-06-06 20:45:41 +0000 | [diff] [blame] | 5276 |         SMI.shouldDeleteForField(*FI)) | 
| Sean Hunt | e340682 | 2011-05-20 21:43:47 +0000 | [diff] [blame] | 5277 |       return true; | 
| Sean Hunt | cdee3fe | 2011-05-11 22:34:38 +0000 | [diff] [blame] | 5278 |  | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 5279 |   if (SMI.shouldDeleteForAllConstMembers()) | 
| Sean Hunt | cdee3fe | 2011-05-11 22:34:38 +0000 | [diff] [blame] | 5280 |     return true; | 
 | 5281 |  | 
 | 5282 |   return false; | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5283 | } | 
 | 5284 |  | 
| Richard Smith | ac71351 | 2012-12-08 02:53:02 +0000 | [diff] [blame] | 5285 | /// Perform lookup for a special member of the specified kind, and determine | 
 | 5286 | /// whether it is trivial. If the triviality can be determined without the | 
 | 5287 | /// lookup, skip it. This is intended for use when determining whether a | 
 | 5288 | /// special member of a containing object is trivial, and thus does not ever | 
 | 5289 | /// perform overload resolution for default constructors. | 
 | 5290 | /// | 
 | 5291 | /// If \p Selected is not \c NULL, \c *Selected will be filled in with the | 
 | 5292 | /// member that was most likely to be intended to be trivial, if any. | 
 | 5293 | static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD, | 
 | 5294 |                                      Sema::CXXSpecialMember CSM, unsigned Quals, | 
 | 5295 |                                      CXXMethodDecl **Selected) { | 
 | 5296 |   if (Selected) | 
 | 5297 |     *Selected = 0; | 
 | 5298 |  | 
 | 5299 |   switch (CSM) { | 
 | 5300 |   case Sema::CXXInvalid: | 
 | 5301 |     llvm_unreachable("not a special member"); | 
 | 5302 |  | 
 | 5303 |   case Sema::CXXDefaultConstructor: | 
 | 5304 |     // C++11 [class.ctor]p5: | 
 | 5305 |     //   A default constructor is trivial if: | 
 | 5306 |     //    - all the [direct subobjects] have trivial default constructors | 
 | 5307 |     // | 
 | 5308 |     // Note, no overload resolution is performed in this case. | 
 | 5309 |     if (RD->hasTrivialDefaultConstructor()) | 
 | 5310 |       return true; | 
 | 5311 |  | 
 | 5312 |     if (Selected) { | 
 | 5313 |       // If there's a default constructor which could have been trivial, dig it | 
 | 5314 |       // out. Otherwise, if there's any user-provided default constructor, point | 
 | 5315 |       // to that as an example of why there's not a trivial one. | 
 | 5316 |       CXXConstructorDecl *DefCtor = 0; | 
 | 5317 |       if (RD->needsImplicitDefaultConstructor()) | 
 | 5318 |         S.DeclareImplicitDefaultConstructor(RD); | 
 | 5319 |       for (CXXRecordDecl::ctor_iterator CI = RD->ctor_begin(), | 
 | 5320 |                                         CE = RD->ctor_end(); CI != CE; ++CI) { | 
 | 5321 |         if (!CI->isDefaultConstructor()) | 
 | 5322 |           continue; | 
 | 5323 |         DefCtor = *CI; | 
 | 5324 |         if (!DefCtor->isUserProvided()) | 
 | 5325 |           break; | 
 | 5326 |       } | 
 | 5327 |  | 
 | 5328 |       *Selected = DefCtor; | 
 | 5329 |     } | 
 | 5330 |  | 
 | 5331 |     return false; | 
 | 5332 |  | 
 | 5333 |   case Sema::CXXDestructor: | 
 | 5334 |     // C++11 [class.dtor]p5: | 
 | 5335 |     //   A destructor is trivial if: | 
 | 5336 |     //    - all the direct [subobjects] have trivial destructors | 
 | 5337 |     if (RD->hasTrivialDestructor()) | 
 | 5338 |       return true; | 
 | 5339 |  | 
 | 5340 |     if (Selected) { | 
 | 5341 |       if (RD->needsImplicitDestructor()) | 
 | 5342 |         S.DeclareImplicitDestructor(RD); | 
 | 5343 |       *Selected = RD->getDestructor(); | 
 | 5344 |     } | 
 | 5345 |  | 
 | 5346 |     return false; | 
 | 5347 |  | 
 | 5348 |   case Sema::CXXCopyConstructor: | 
 | 5349 |     // C++11 [class.copy]p12: | 
 | 5350 |     //   A copy constructor is trivial if: | 
 | 5351 |     //    - the constructor selected to copy each direct [subobject] is trivial | 
 | 5352 |     if (RD->hasTrivialCopyConstructor()) { | 
 | 5353 |       if (Quals == Qualifiers::Const) | 
 | 5354 |         // We must either select the trivial copy constructor or reach an | 
 | 5355 |         // ambiguity; no need to actually perform overload resolution. | 
 | 5356 |         return true; | 
 | 5357 |     } else if (!Selected) { | 
 | 5358 |       return false; | 
 | 5359 |     } | 
 | 5360 |     // In C++98, we are not supposed to perform overload resolution here, but we | 
 | 5361 |     // treat that as a language defect, as suggested on cxx-abi-dev, to treat | 
 | 5362 |     // cases like B as having a non-trivial copy constructor: | 
 | 5363 |     //   struct A { template<typename T> A(T&); }; | 
 | 5364 |     //   struct B { mutable A a; }; | 
 | 5365 |     goto NeedOverloadResolution; | 
 | 5366 |  | 
 | 5367 |   case Sema::CXXCopyAssignment: | 
 | 5368 |     // C++11 [class.copy]p25: | 
 | 5369 |     //   A copy assignment operator is trivial if: | 
 | 5370 |     //    - the assignment operator selected to copy each direct [subobject] is | 
 | 5371 |     //      trivial | 
 | 5372 |     if (RD->hasTrivialCopyAssignment()) { | 
 | 5373 |       if (Quals == Qualifiers::Const) | 
 | 5374 |         return true; | 
 | 5375 |     } else if (!Selected) { | 
 | 5376 |       return false; | 
 | 5377 |     } | 
 | 5378 |     // In C++98, we are not supposed to perform overload resolution here, but we | 
 | 5379 |     // treat that as a language defect. | 
 | 5380 |     goto NeedOverloadResolution; | 
 | 5381 |  | 
 | 5382 |   case Sema::CXXMoveConstructor: | 
 | 5383 |   case Sema::CXXMoveAssignment: | 
 | 5384 |   NeedOverloadResolution: | 
 | 5385 |     Sema::SpecialMemberOverloadResult *SMOR = | 
 | 5386 |       S.LookupSpecialMember(RD, CSM, | 
 | 5387 |                             Quals & Qualifiers::Const, | 
 | 5388 |                             Quals & Qualifiers::Volatile, | 
 | 5389 |                             /*RValueThis*/false, /*ConstThis*/false, | 
 | 5390 |                             /*VolatileThis*/false); | 
 | 5391 |  | 
 | 5392 |     // The standard doesn't describe how to behave if the lookup is ambiguous. | 
 | 5393 |     // We treat it as not making the member non-trivial, just like the standard | 
 | 5394 |     // mandates for the default constructor. This should rarely matter, because | 
 | 5395 |     // the member will also be deleted. | 
 | 5396 |     if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::Ambiguous) | 
 | 5397 |       return true; | 
 | 5398 |  | 
 | 5399 |     if (!SMOR->getMethod()) { | 
 | 5400 |       assert(SMOR->getKind() == | 
 | 5401 |              Sema::SpecialMemberOverloadResult::NoMemberOrDeleted); | 
 | 5402 |       return false; | 
 | 5403 |     } | 
 | 5404 |  | 
 | 5405 |     // We deliberately don't check if we found a deleted special member. We're | 
 | 5406 |     // not supposed to! | 
 | 5407 |     if (Selected) | 
 | 5408 |       *Selected = SMOR->getMethod(); | 
 | 5409 |     return SMOR->getMethod()->isTrivial(); | 
 | 5410 |   } | 
 | 5411 |  | 
 | 5412 |   llvm_unreachable("unknown special method kind"); | 
 | 5413 | } | 
 | 5414 |  | 
| Benjamin Kramer | a574c89 | 2013-02-15 12:30:38 +0000 | [diff] [blame] | 5415 | static CXXConstructorDecl *findUserDeclaredCtor(CXXRecordDecl *RD) { | 
| Richard Smith | ac71351 | 2012-12-08 02:53:02 +0000 | [diff] [blame] | 5416 |   for (CXXRecordDecl::ctor_iterator CI = RD->ctor_begin(), CE = RD->ctor_end(); | 
 | 5417 |        CI != CE; ++CI) | 
 | 5418 |     if (!CI->isImplicit()) | 
 | 5419 |       return *CI; | 
 | 5420 |  | 
 | 5421 |   // Look for constructor templates. | 
 | 5422 |   typedef CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl> tmpl_iter; | 
 | 5423 |   for (tmpl_iter TI(RD->decls_begin()), TE(RD->decls_end()); TI != TE; ++TI) { | 
 | 5424 |     if (CXXConstructorDecl *CD = | 
 | 5425 |           dyn_cast<CXXConstructorDecl>(TI->getTemplatedDecl())) | 
 | 5426 |       return CD; | 
 | 5427 |   } | 
 | 5428 |  | 
 | 5429 |   return 0; | 
 | 5430 | } | 
 | 5431 |  | 
 | 5432 | /// The kind of subobject we are checking for triviality. The values of this | 
 | 5433 | /// enumeration are used in diagnostics. | 
 | 5434 | enum TrivialSubobjectKind { | 
 | 5435 |   /// The subobject is a base class. | 
 | 5436 |   TSK_BaseClass, | 
 | 5437 |   /// The subobject is a non-static data member. | 
 | 5438 |   TSK_Field, | 
 | 5439 |   /// The object is actually the complete object. | 
 | 5440 |   TSK_CompleteObject | 
 | 5441 | }; | 
 | 5442 |  | 
 | 5443 | /// Check whether the special member selected for a given type would be trivial. | 
 | 5444 | static bool checkTrivialSubobjectCall(Sema &S, SourceLocation SubobjLoc, | 
 | 5445 |                                       QualType SubType, | 
 | 5446 |                                       Sema::CXXSpecialMember CSM, | 
 | 5447 |                                       TrivialSubobjectKind Kind, | 
 | 5448 |                                       bool Diagnose) { | 
 | 5449 |   CXXRecordDecl *SubRD = SubType->getAsCXXRecordDecl(); | 
 | 5450 |   if (!SubRD) | 
 | 5451 |     return true; | 
 | 5452 |  | 
 | 5453 |   CXXMethodDecl *Selected; | 
 | 5454 |   if (findTrivialSpecialMember(S, SubRD, CSM, SubType.getCVRQualifiers(), | 
 | 5455 |                                Diagnose ? &Selected : 0)) | 
 | 5456 |     return true; | 
 | 5457 |  | 
 | 5458 |   if (Diagnose) { | 
 | 5459 |     if (!Selected && CSM == Sema::CXXDefaultConstructor) { | 
 | 5460 |       S.Diag(SubobjLoc, diag::note_nontrivial_no_def_ctor) | 
 | 5461 |         << Kind << SubType.getUnqualifiedType(); | 
 | 5462 |       if (CXXConstructorDecl *CD = findUserDeclaredCtor(SubRD)) | 
 | 5463 |         S.Diag(CD->getLocation(), diag::note_user_declared_ctor); | 
 | 5464 |     } else if (!Selected) | 
 | 5465 |       S.Diag(SubobjLoc, diag::note_nontrivial_no_copy) | 
 | 5466 |         << Kind << SubType.getUnqualifiedType() << CSM << SubType; | 
 | 5467 |     else if (Selected->isUserProvided()) { | 
 | 5468 |       if (Kind == TSK_CompleteObject) | 
 | 5469 |         S.Diag(Selected->getLocation(), diag::note_nontrivial_user_provided) | 
 | 5470 |           << Kind << SubType.getUnqualifiedType() << CSM; | 
 | 5471 |       else { | 
 | 5472 |         S.Diag(SubobjLoc, diag::note_nontrivial_user_provided) | 
 | 5473 |           << Kind << SubType.getUnqualifiedType() << CSM; | 
 | 5474 |         S.Diag(Selected->getLocation(), diag::note_declared_at); | 
 | 5475 |       } | 
 | 5476 |     } else { | 
 | 5477 |       if (Kind != TSK_CompleteObject) | 
 | 5478 |         S.Diag(SubobjLoc, diag::note_nontrivial_subobject) | 
 | 5479 |           << Kind << SubType.getUnqualifiedType() << CSM; | 
 | 5480 |  | 
 | 5481 |       // Explain why the defaulted or deleted special member isn't trivial. | 
 | 5482 |       S.SpecialMemberIsTrivial(Selected, CSM, Diagnose); | 
 | 5483 |     } | 
 | 5484 |   } | 
 | 5485 |  | 
 | 5486 |   return false; | 
 | 5487 | } | 
 | 5488 |  | 
 | 5489 | /// Check whether the members of a class type allow a special member to be | 
 | 5490 | /// trivial. | 
 | 5491 | static bool checkTrivialClassMembers(Sema &S, CXXRecordDecl *RD, | 
 | 5492 |                                      Sema::CXXSpecialMember CSM, | 
 | 5493 |                                      bool ConstArg, bool Diagnose) { | 
 | 5494 |   for (CXXRecordDecl::field_iterator FI = RD->field_begin(), | 
 | 5495 |                                      FE = RD->field_end(); FI != FE; ++FI) { | 
 | 5496 |     if (FI->isInvalidDecl() || FI->isUnnamedBitfield()) | 
 | 5497 |       continue; | 
 | 5498 |  | 
 | 5499 |     QualType FieldType = S.Context.getBaseElementType(FI->getType()); | 
 | 5500 |  | 
 | 5501 |     // Pretend anonymous struct or union members are members of this class. | 
 | 5502 |     if (FI->isAnonymousStructOrUnion()) { | 
 | 5503 |       if (!checkTrivialClassMembers(S, FieldType->getAsCXXRecordDecl(), | 
 | 5504 |                                     CSM, ConstArg, Diagnose)) | 
 | 5505 |         return false; | 
 | 5506 |       continue; | 
 | 5507 |     } | 
 | 5508 |  | 
 | 5509 |     // C++11 [class.ctor]p5: | 
 | 5510 |     //   A default constructor is trivial if [...] | 
 | 5511 |     //    -- no non-static data member of its class has a | 
 | 5512 |     //       brace-or-equal-initializer | 
 | 5513 |     if (CSM == Sema::CXXDefaultConstructor && FI->hasInClassInitializer()) { | 
 | 5514 |       if (Diagnose) | 
 | 5515 |         S.Diag(FI->getLocation(), diag::note_nontrivial_in_class_init) << *FI; | 
 | 5516 |       return false; | 
 | 5517 |     } | 
 | 5518 |  | 
 | 5519 |     // Objective C ARC 4.3.5: | 
 | 5520 |     //   [...] nontrivally ownership-qualified types are [...] not trivially | 
 | 5521 |     //   default constructible, copy constructible, move constructible, copy | 
 | 5522 |     //   assignable, move assignable, or destructible [...] | 
 | 5523 |     if (S.getLangOpts().ObjCAutoRefCount && | 
 | 5524 |         FieldType.hasNonTrivialObjCLifetime()) { | 
 | 5525 |       if (Diagnose) | 
 | 5526 |         S.Diag(FI->getLocation(), diag::note_nontrivial_objc_ownership) | 
 | 5527 |           << RD << FieldType.getObjCLifetime(); | 
 | 5528 |       return false; | 
 | 5529 |     } | 
 | 5530 |  | 
 | 5531 |     if (ConstArg && !FI->isMutable()) | 
 | 5532 |       FieldType.addConst(); | 
 | 5533 |     if (!checkTrivialSubobjectCall(S, FI->getLocation(), FieldType, CSM, | 
 | 5534 |                                    TSK_Field, Diagnose)) | 
 | 5535 |       return false; | 
 | 5536 |   } | 
 | 5537 |  | 
 | 5538 |   return true; | 
 | 5539 | } | 
 | 5540 |  | 
 | 5541 | /// Diagnose why the specified class does not have a trivial special member of | 
 | 5542 | /// the given kind. | 
 | 5543 | void Sema::DiagnoseNontrivial(const CXXRecordDecl *RD, CXXSpecialMember CSM) { | 
 | 5544 |   QualType Ty = Context.getRecordType(RD); | 
 | 5545 |   if (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment) | 
 | 5546 |     Ty.addConst(); | 
 | 5547 |  | 
 | 5548 |   checkTrivialSubobjectCall(*this, RD->getLocation(), Ty, CSM, | 
 | 5549 |                             TSK_CompleteObject, /*Diagnose*/true); | 
 | 5550 | } | 
 | 5551 |  | 
 | 5552 | /// Determine whether a defaulted or deleted special member function is trivial, | 
 | 5553 | /// as specified in C++11 [class.ctor]p5, C++11 [class.copy]p12, | 
 | 5554 | /// C++11 [class.copy]p25, and C++11 [class.dtor]p5. | 
 | 5555 | bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM, | 
 | 5556 |                                   bool Diagnose) { | 
| Richard Smith | ac71351 | 2012-12-08 02:53:02 +0000 | [diff] [blame] | 5557 |   assert(!MD->isUserProvided() && CSM != CXXInvalid && "not special enough"); | 
 | 5558 |  | 
 | 5559 |   CXXRecordDecl *RD = MD->getParent(); | 
 | 5560 |  | 
 | 5561 |   bool ConstArg = false; | 
| Richard Smith | ac71351 | 2012-12-08 02:53:02 +0000 | [diff] [blame] | 5562 |  | 
 | 5563 |   // C++11 [class.copy]p12, p25: | 
 | 5564 |   //   A [special member] is trivial if its declared parameter type is the same | 
 | 5565 |   //   as if it had been implicitly declared [...] | 
 | 5566 |   switch (CSM) { | 
 | 5567 |   case CXXDefaultConstructor: | 
 | 5568 |   case CXXDestructor: | 
 | 5569 |     // Trivial default constructors and destructors cannot have parameters. | 
 | 5570 |     break; | 
 | 5571 |  | 
 | 5572 |   case CXXCopyConstructor: | 
 | 5573 |   case CXXCopyAssignment: { | 
 | 5574 |     // Trivial copy operations always have const, non-volatile parameter types. | 
 | 5575 |     ConstArg = true; | 
| Jordan Rose | 41f3f3a | 2013-03-05 01:27:54 +0000 | [diff] [blame] | 5576 |     const ParmVarDecl *Param0 = MD->getParamDecl(0); | 
| Richard Smith | ac71351 | 2012-12-08 02:53:02 +0000 | [diff] [blame] | 5577 |     const ReferenceType *RT = Param0->getType()->getAs<ReferenceType>(); | 
 | 5578 |     if (!RT || RT->getPointeeType().getCVRQualifiers() != Qualifiers::Const) { | 
 | 5579 |       if (Diagnose) | 
 | 5580 |         Diag(Param0->getLocation(), diag::note_nontrivial_param_type) | 
 | 5581 |           << Param0->getSourceRange() << Param0->getType() | 
 | 5582 |           << Context.getLValueReferenceType( | 
 | 5583 |                Context.getRecordType(RD).withConst()); | 
 | 5584 |       return false; | 
 | 5585 |     } | 
 | 5586 |     break; | 
 | 5587 |   } | 
 | 5588 |  | 
 | 5589 |   case CXXMoveConstructor: | 
 | 5590 |   case CXXMoveAssignment: { | 
 | 5591 |     // Trivial move operations always have non-cv-qualified parameters. | 
| Jordan Rose | 41f3f3a | 2013-03-05 01:27:54 +0000 | [diff] [blame] | 5592 |     const ParmVarDecl *Param0 = MD->getParamDecl(0); | 
| Richard Smith | ac71351 | 2012-12-08 02:53:02 +0000 | [diff] [blame] | 5593 |     const RValueReferenceType *RT = | 
 | 5594 |       Param0->getType()->getAs<RValueReferenceType>(); | 
 | 5595 |     if (!RT || RT->getPointeeType().getCVRQualifiers()) { | 
 | 5596 |       if (Diagnose) | 
 | 5597 |         Diag(Param0->getLocation(), diag::note_nontrivial_param_type) | 
 | 5598 |           << Param0->getSourceRange() << Param0->getType() | 
 | 5599 |           << Context.getRValueReferenceType(Context.getRecordType(RD)); | 
 | 5600 |       return false; | 
 | 5601 |     } | 
 | 5602 |     break; | 
 | 5603 |   } | 
 | 5604 |  | 
 | 5605 |   case CXXInvalid: | 
 | 5606 |     llvm_unreachable("not a special member"); | 
 | 5607 |   } | 
 | 5608 |  | 
 | 5609 |   // FIXME: We require that the parameter-declaration-clause is equivalent to | 
 | 5610 |   // that of an implicit declaration, not just that the declared parameter type | 
 | 5611 |   // matches, in order to prevent absuridities like a function simultaneously | 
 | 5612 |   // being a trivial copy constructor and a non-trivial default constructor. | 
 | 5613 |   // This issue has not yet been assigned a core issue number. | 
 | 5614 |   if (MD->getMinRequiredArguments() < MD->getNumParams()) { | 
 | 5615 |     if (Diagnose) | 
 | 5616 |       Diag(MD->getParamDecl(MD->getMinRequiredArguments())->getLocation(), | 
 | 5617 |            diag::note_nontrivial_default_arg) | 
 | 5618 |         << MD->getParamDecl(MD->getMinRequiredArguments())->getSourceRange(); | 
 | 5619 |     return false; | 
 | 5620 |   } | 
 | 5621 |   if (MD->isVariadic()) { | 
 | 5622 |     if (Diagnose) | 
 | 5623 |       Diag(MD->getLocation(), diag::note_nontrivial_variadic); | 
 | 5624 |     return false; | 
 | 5625 |   } | 
 | 5626 |  | 
 | 5627 |   // C++11 [class.ctor]p5, C++11 [class.dtor]p5: | 
 | 5628 |   //   A copy/move [constructor or assignment operator] is trivial if | 
 | 5629 |   //    -- the [member] selected to copy/move each direct base class subobject | 
 | 5630 |   //       is trivial | 
 | 5631 |   // | 
 | 5632 |   // C++11 [class.copy]p12, C++11 [class.copy]p25: | 
 | 5633 |   //   A [default constructor or destructor] is trivial if | 
 | 5634 |   //    -- all the direct base classes have trivial [default constructors or | 
 | 5635 |   //       destructors] | 
 | 5636 |   for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(), | 
 | 5637 |                                           BE = RD->bases_end(); BI != BE; ++BI) | 
 | 5638 |     if (!checkTrivialSubobjectCall(*this, BI->getLocStart(), | 
 | 5639 |                                    ConstArg ? BI->getType().withConst() | 
 | 5640 |                                             : BI->getType(), | 
 | 5641 |                                    CSM, TSK_BaseClass, Diagnose)) | 
 | 5642 |       return false; | 
 | 5643 |  | 
 | 5644 |   // C++11 [class.ctor]p5, C++11 [class.dtor]p5: | 
 | 5645 |   //   A copy/move [constructor or assignment operator] for a class X is | 
 | 5646 |   //   trivial if | 
 | 5647 |   //    -- for each non-static data member of X that is of class type (or array | 
 | 5648 |   //       thereof), the constructor selected to copy/move that member is | 
 | 5649 |   //       trivial | 
 | 5650 |   // | 
 | 5651 |   // C++11 [class.copy]p12, C++11 [class.copy]p25: | 
 | 5652 |   //   A [default constructor or destructor] is trivial if | 
 | 5653 |   //    -- for all of the non-static data members of its class that are of class | 
 | 5654 |   //       type (or array thereof), each such class has a trivial [default | 
 | 5655 |   //       constructor or destructor] | 
 | 5656 |   if (!checkTrivialClassMembers(*this, RD, CSM, ConstArg, Diagnose)) | 
 | 5657 |     return false; | 
 | 5658 |  | 
 | 5659 |   // C++11 [class.dtor]p5: | 
 | 5660 |   //   A destructor is trivial if [...] | 
 | 5661 |   //    -- the destructor is not virtual | 
 | 5662 |   if (CSM == CXXDestructor && MD->isVirtual()) { | 
 | 5663 |     if (Diagnose) | 
 | 5664 |       Diag(MD->getLocation(), diag::note_nontrivial_virtual_dtor) << RD; | 
 | 5665 |     return false; | 
 | 5666 |   } | 
 | 5667 |  | 
 | 5668 |   // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25: | 
 | 5669 |   //   A [special member] for class X is trivial if [...] | 
 | 5670 |   //    -- class X has no virtual functions and no virtual base classes | 
 | 5671 |   if (CSM != CXXDestructor && MD->getParent()->isDynamicClass()) { | 
 | 5672 |     if (!Diagnose) | 
 | 5673 |       return false; | 
 | 5674 |  | 
 | 5675 |     if (RD->getNumVBases()) { | 
 | 5676 |       // Check for virtual bases. We already know that the corresponding | 
 | 5677 |       // member in all bases is trivial, so vbases must all be direct. | 
 | 5678 |       CXXBaseSpecifier &BS = *RD->vbases_begin(); | 
 | 5679 |       assert(BS.isVirtual()); | 
 | 5680 |       Diag(BS.getLocStart(), diag::note_nontrivial_has_virtual) << RD << 1; | 
 | 5681 |       return false; | 
 | 5682 |     } | 
 | 5683 |  | 
 | 5684 |     // Must have a virtual method. | 
 | 5685 |     for (CXXRecordDecl::method_iterator MI = RD->method_begin(), | 
 | 5686 |                                         ME = RD->method_end(); MI != ME; ++MI) { | 
 | 5687 |       if (MI->isVirtual()) { | 
 | 5688 |         SourceLocation MLoc = MI->getLocStart(); | 
 | 5689 |         Diag(MLoc, diag::note_nontrivial_has_virtual) << RD << 0; | 
 | 5690 |         return false; | 
 | 5691 |       } | 
 | 5692 |     } | 
 | 5693 |  | 
 | 5694 |     llvm_unreachable("dynamic class with no vbases and no virtual functions"); | 
 | 5695 |   } | 
 | 5696 |  | 
 | 5697 |   // Looks like it's trivial! | 
 | 5698 |   return true; | 
 | 5699 | } | 
 | 5700 |  | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5701 | /// \brief Data used with FindHiddenVirtualMethod | 
| Benjamin Kramer | c54061a | 2011-03-04 13:12:48 +0000 | [diff] [blame] | 5702 | namespace { | 
 | 5703 |   struct FindHiddenVirtualMethodData { | 
 | 5704 |     Sema *S; | 
 | 5705 |     CXXMethodDecl *Method; | 
 | 5706 |     llvm::SmallPtrSet<const CXXMethodDecl *, 8> OverridenAndUsingBaseMethods; | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 5707 |     SmallVector<CXXMethodDecl *, 8> OverloadedMethods; | 
| Benjamin Kramer | c54061a | 2011-03-04 13:12:48 +0000 | [diff] [blame] | 5708 |   }; | 
 | 5709 | } | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5710 |  | 
| David Blaikie | 5f75068 | 2012-10-19 00:53:08 +0000 | [diff] [blame] | 5711 | /// \brief Check whether any most overriden method from MD in Methods | 
 | 5712 | static bool CheckMostOverridenMethods(const CXXMethodDecl *MD, | 
 | 5713 |                    const llvm::SmallPtrSet<const CXXMethodDecl *, 8>& Methods) { | 
 | 5714 |   if (MD->size_overridden_methods() == 0) | 
 | 5715 |     return Methods.count(MD->getCanonicalDecl()); | 
 | 5716 |   for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), | 
 | 5717 |                                       E = MD->end_overridden_methods(); | 
 | 5718 |        I != E; ++I) | 
 | 5719 |     if (CheckMostOverridenMethods(*I, Methods)) | 
 | 5720 |       return true; | 
 | 5721 |   return false; | 
 | 5722 | } | 
 | 5723 |  | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5724 | /// \brief Member lookup function that determines whether a given C++ | 
 | 5725 | /// method overloads virtual methods in a base class without overriding any, | 
 | 5726 | /// to be used with CXXRecordDecl::lookupInBases(). | 
 | 5727 | static bool FindHiddenVirtualMethod(const CXXBaseSpecifier *Specifier, | 
 | 5728 |                                     CXXBasePath &Path, | 
 | 5729 |                                     void *UserData) { | 
 | 5730 |   RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl(); | 
 | 5731 |  | 
 | 5732 |   FindHiddenVirtualMethodData &Data | 
 | 5733 |     = *static_cast<FindHiddenVirtualMethodData*>(UserData); | 
 | 5734 |  | 
 | 5735 |   DeclarationName Name = Data.Method->getDeclName(); | 
 | 5736 |   assert(Name.getNameKind() == DeclarationName::Identifier); | 
 | 5737 |  | 
 | 5738 |   bool foundSameNameMethod = false; | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 5739 |   SmallVector<CXXMethodDecl *, 8> overloadedMethods; | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5740 |   for (Path.Decls = BaseRecord->lookup(Name); | 
| David Blaikie | 3bc93e3 | 2012-12-19 00:45:41 +0000 | [diff] [blame] | 5741 |        !Path.Decls.empty(); | 
 | 5742 |        Path.Decls = Path.Decls.slice(1)) { | 
 | 5743 |     NamedDecl *D = Path.Decls.front(); | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5744 |     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { | 
| Argyrios Kyrtzidis | 74b47f9 | 2011-02-10 18:13:41 +0000 | [diff] [blame] | 5745 |       MD = MD->getCanonicalDecl(); | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5746 |       foundSameNameMethod = true; | 
 | 5747 |       // Interested only in hidden virtual methods. | 
 | 5748 |       if (!MD->isVirtual()) | 
 | 5749 |         continue; | 
 | 5750 |       // If the method we are checking overrides a method from its base | 
 | 5751 |       // don't warn about the other overloaded methods. | 
 | 5752 |       if (!Data.S->IsOverload(Data.Method, MD, false)) | 
 | 5753 |         return true; | 
 | 5754 |       // Collect the overload only if its hidden. | 
| David Blaikie | 5f75068 | 2012-10-19 00:53:08 +0000 | [diff] [blame] | 5755 |       if (!CheckMostOverridenMethods(MD, Data.OverridenAndUsingBaseMethods)) | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5756 |         overloadedMethods.push_back(MD); | 
 | 5757 |     } | 
 | 5758 |   } | 
 | 5759 |  | 
 | 5760 |   if (foundSameNameMethod) | 
 | 5761 |     Data.OverloadedMethods.append(overloadedMethods.begin(), | 
 | 5762 |                                    overloadedMethods.end()); | 
 | 5763 |   return foundSameNameMethod; | 
 | 5764 | } | 
 | 5765 |  | 
| David Blaikie | 5f75068 | 2012-10-19 00:53:08 +0000 | [diff] [blame] | 5766 | /// \brief Add the most overriden methods from MD to Methods | 
 | 5767 | static void AddMostOverridenMethods(const CXXMethodDecl *MD, | 
 | 5768 |                          llvm::SmallPtrSet<const CXXMethodDecl *, 8>& Methods) { | 
 | 5769 |   if (MD->size_overridden_methods() == 0) | 
 | 5770 |     Methods.insert(MD->getCanonicalDecl()); | 
 | 5771 |   for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), | 
 | 5772 |                                       E = MD->end_overridden_methods(); | 
 | 5773 |        I != E; ++I) | 
 | 5774 |     AddMostOverridenMethods(*I, Methods); | 
 | 5775 | } | 
 | 5776 |  | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 5777 | /// \brief Check if a method overloads virtual methods in a base class without | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5778 | /// overriding any. | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 5779 | void Sema::FindHiddenVirtualMethods(CXXMethodDecl *MD, | 
 | 5780 |                           SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods) { | 
| Benjamin Kramer | c470442 | 2012-05-19 16:03:58 +0000 | [diff] [blame] | 5781 |   if (!MD->getDeclName().isIdentifier()) | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5782 |     return; | 
 | 5783 |  | 
 | 5784 |   CXXBasePaths Paths(/*FindAmbiguities=*/true, // true to look in all bases. | 
 | 5785 |                      /*bool RecordPaths=*/false, | 
 | 5786 |                      /*bool DetectVirtual=*/false); | 
 | 5787 |   FindHiddenVirtualMethodData Data; | 
 | 5788 |   Data.Method = MD; | 
 | 5789 |   Data.S = this; | 
 | 5790 |  | 
 | 5791 |   // Keep the base methods that were overriden or introduced in the subclass | 
 | 5792 |   // by 'using' in a set. A base method not in this set is hidden. | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 5793 |   CXXRecordDecl *DC = MD->getParent(); | 
| David Blaikie | 3bc93e3 | 2012-12-19 00:45:41 +0000 | [diff] [blame] | 5794 |   DeclContext::lookup_result R = DC->lookup(MD->getDeclName()); | 
 | 5795 |   for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) { | 
 | 5796 |     NamedDecl *ND = *I; | 
 | 5797 |     if (UsingShadowDecl *shad = dyn_cast<UsingShadowDecl>(*I)) | 
| David Blaikie | 5f75068 | 2012-10-19 00:53:08 +0000 | [diff] [blame] | 5798 |       ND = shad->getTargetDecl(); | 
 | 5799 |     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND)) | 
 | 5800 |       AddMostOverridenMethods(MD, Data.OverridenAndUsingBaseMethods); | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5801 |   } | 
 | 5802 |  | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 5803 |   if (DC->lookupInBases(&FindHiddenVirtualMethod, &Data, Paths)) | 
 | 5804 |     OverloadedMethods = Data.OverloadedMethods; | 
 | 5805 | } | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5806 |  | 
| Eli Friedman | dae9271 | 2013-09-05 23:51:03 +0000 | [diff] [blame] | 5807 | void Sema::NoteHiddenVirtualMethods(CXXMethodDecl *MD, | 
 | 5808 |                           SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods) { | 
 | 5809 |   for (unsigned i = 0, e = OverloadedMethods.size(); i != e; ++i) { | 
 | 5810 |     CXXMethodDecl *overloadedMD = OverloadedMethods[i]; | 
 | 5811 |     PartialDiagnostic PD = PDiag( | 
 | 5812 |          diag::note_hidden_overloaded_virtual_declared_here) << overloadedMD; | 
 | 5813 |     HandleFunctionTypeMismatch(PD, MD->getType(), overloadedMD->getType()); | 
 | 5814 |     Diag(overloadedMD->getLocation(), PD); | 
 | 5815 |   } | 
 | 5816 | } | 
 | 5817 |  | 
 | 5818 | /// \brief Diagnose methods which overload virtual methods in a base class | 
 | 5819 | /// without overriding any. | 
 | 5820 | void Sema::DiagnoseHiddenVirtualMethods(CXXMethodDecl *MD) { | 
 | 5821 |   if (MD->isInvalidDecl()) | 
 | 5822 |     return; | 
 | 5823 |  | 
 | 5824 |   if (Diags.getDiagnosticLevel(diag::warn_overloaded_virtual, | 
 | 5825 |                                MD->getLocation()) == DiagnosticsEngine::Ignored) | 
 | 5826 |     return; | 
 | 5827 |  | 
 | 5828 |   SmallVector<CXXMethodDecl *, 8> OverloadedMethods; | 
 | 5829 |   FindHiddenVirtualMethods(MD, OverloadedMethods); | 
 | 5830 |   if (!OverloadedMethods.empty()) { | 
 | 5831 |     Diag(MD->getLocation(), diag::warn_overloaded_virtual) | 
 | 5832 |       << MD << (OverloadedMethods.size() > 1); | 
 | 5833 |  | 
 | 5834 |     NoteHiddenVirtualMethods(MD, OverloadedMethods); | 
| Argyrios Kyrtzidis | 799ef66 | 2011-02-03 18:01:15 +0000 | [diff] [blame] | 5835 |   } | 
| Douglas Gregor | 1ab537b | 2009-12-03 18:33:45 +0000 | [diff] [blame] | 5836 | } | 
 | 5837 |  | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 5838 | void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5839 |                                              Decl *TagDecl, | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 5840 |                                              SourceLocation LBrac, | 
| Douglas Gregor | 0b4c9b5 | 2010-03-29 14:42:08 +0000 | [diff] [blame] | 5841 |                                              SourceLocation RBrac, | 
 | 5842 |                                              AttributeList *AttrList) { | 
| Douglas Gregor | 4c4f7cb | 2009-06-22 23:20:33 +0000 | [diff] [blame] | 5843 |   if (!TagDecl) | 
 | 5844 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5845 |  | 
| Douglas Gregor | 42af25f | 2009-05-11 19:58:34 +0000 | [diff] [blame] | 5846 |   AdjustDeclIfTemplate(TagDecl); | 
| Douglas Gregor | 1ab537b | 2009-12-03 18:33:45 +0000 | [diff] [blame] | 5847 |  | 
| Rafael Espindola | f729ce0 | 2012-07-12 04:32:30 +0000 | [diff] [blame] | 5848 |   for (const AttributeList* l = AttrList; l; l = l->getNext()) { | 
 | 5849 |     if (l->getKind() != AttributeList::AT_Visibility) | 
 | 5850 |       continue; | 
 | 5851 |     l->setInvalid(); | 
 | 5852 |     Diag(l->getLoc(), diag::warn_attribute_after_definition_ignored) << | 
 | 5853 |       l->getName(); | 
 | 5854 |   } | 
 | 5855 |  | 
| David Blaikie | 77b6de0 | 2011-09-22 02:58:26 +0000 | [diff] [blame] | 5856 |   ActOnFields(S, RLoc, TagDecl, llvm::makeArrayRef( | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5857 |               // strict aliasing violation! | 
 | 5858 |               reinterpret_cast<Decl**>(FieldCollector->getCurFields()), | 
| David Blaikie | 77b6de0 | 2011-09-22 02:58:26 +0000 | [diff] [blame] | 5859 |               FieldCollector->getCurNumFields()), LBrac, RBrac, AttrList); | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 5860 |  | 
| Douglas Gregor | 23c94db | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 5861 |   CheckCompletedCXXClass( | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5862 |                         dyn_cast_or_null<CXXRecordDecl>(TagDecl)); | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 5863 | } | 
 | 5864 |  | 
| Douglas Gregor | 396b7cd | 2008-11-03 17:51:48 +0000 | [diff] [blame] | 5865 | /// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared | 
 | 5866 | /// special functions, such as the default constructor, copy | 
 | 5867 | /// constructor, or destructor, to the given C++ class (C++ | 
 | 5868 | /// [special]p1).  This routine can only be executed just before the | 
 | 5869 | /// definition of the class is complete. | 
| Douglas Gregor | 23c94db | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 5870 | void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { | 
| Douglas Gregor | 32df23e | 2010-07-01 22:02:46 +0000 | [diff] [blame] | 5871 |   if (!ClassDecl->hasUserDeclaredConstructor()) | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 5872 |     ++ASTContext::NumImplicitDefaultConstructors; | 
| Douglas Gregor | 396b7cd | 2008-11-03 17:51:48 +0000 | [diff] [blame] | 5873 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 5874 |   if (!ClassDecl->hasUserDeclaredCopyConstructor()) { | 
| Douglas Gregor | 2258431 | 2010-07-02 23:41:54 +0000 | [diff] [blame] | 5875 |     ++ASTContext::NumImplicitCopyConstructors; | 
| Douglas Gregor | 396b7cd | 2008-11-03 17:51:48 +0000 | [diff] [blame] | 5876 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 5877 |     // If the properties or semantics of the copy constructor couldn't be | 
 | 5878 |     // determined while the class was being declared, force a declaration | 
 | 5879 |     // of it now. | 
 | 5880 |     if (ClassDecl->needsOverloadResolutionForCopyConstructor()) | 
 | 5881 |       DeclareImplicitCopyConstructor(ClassDecl); | 
 | 5882 |   } | 
 | 5883 |  | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 5884 |   if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveConstructor()) { | 
| Richard Smith | b701d3d | 2011-12-24 21:56:24 +0000 | [diff] [blame] | 5885 |     ++ASTContext::NumImplicitMoveConstructors; | 
 | 5886 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 5887 |     if (ClassDecl->needsOverloadResolutionForMoveConstructor()) | 
 | 5888 |       DeclareImplicitMoveConstructor(ClassDecl); | 
 | 5889 |   } | 
 | 5890 |  | 
| Douglas Gregor | a376d10 | 2010-07-02 21:50:04 +0000 | [diff] [blame] | 5891 |   if (!ClassDecl->hasUserDeclaredCopyAssignment()) { | 
 | 5892 |     ++ASTContext::NumImplicitCopyAssignmentOperators; | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 5893 |  | 
 | 5894 |     // If we have a dynamic class, then the copy assignment operator may be | 
| Douglas Gregor | a376d10 | 2010-07-02 21:50:04 +0000 | [diff] [blame] | 5895 |     // virtual, so we have to declare it immediately. This ensures that, e.g., | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 5896 |     // it shows up in the right place in the vtable and that we diagnose | 
 | 5897 |     // problems with the implicit exception specification. | 
 | 5898 |     if (ClassDecl->isDynamicClass() || | 
 | 5899 |         ClassDecl->needsOverloadResolutionForCopyAssignment()) | 
| Douglas Gregor | a376d10 | 2010-07-02 21:50:04 +0000 | [diff] [blame] | 5900 |       DeclareImplicitCopyAssignment(ClassDecl); | 
 | 5901 |   } | 
| Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 5902 |  | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 5903 |   if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveAssignment()) { | 
| Richard Smith | b701d3d | 2011-12-24 21:56:24 +0000 | [diff] [blame] | 5904 |     ++ASTContext::NumImplicitMoveAssignmentOperators; | 
 | 5905 |  | 
 | 5906 |     // Likewise for the move assignment operator. | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 5907 |     if (ClassDecl->isDynamicClass() || | 
 | 5908 |         ClassDecl->needsOverloadResolutionForMoveAssignment()) | 
| Richard Smith | b701d3d | 2011-12-24 21:56:24 +0000 | [diff] [blame] | 5909 |       DeclareImplicitMoveAssignment(ClassDecl); | 
 | 5910 |   } | 
 | 5911 |  | 
| Douglas Gregor | 4923aa2 | 2010-07-02 20:37:36 +0000 | [diff] [blame] | 5912 |   if (!ClassDecl->hasUserDeclaredDestructor()) { | 
 | 5913 |     ++ASTContext::NumImplicitDestructors; | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 5914 |  | 
 | 5915 |     // If we have a dynamic class, then the destructor may be virtual, so we | 
| Douglas Gregor | 4923aa2 | 2010-07-02 20:37:36 +0000 | [diff] [blame] | 5916 |     // have to declare the destructor immediately. This ensures that, e.g., it | 
 | 5917 |     // shows up in the right place in the vtable and that we diagnose problems | 
 | 5918 |     // with the implicit exception specification. | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 5919 |     if (ClassDecl->isDynamicClass() || | 
 | 5920 |         ClassDecl->needsOverloadResolutionForDestructor()) | 
| Douglas Gregor | 4923aa2 | 2010-07-02 20:37:36 +0000 | [diff] [blame] | 5921 |       DeclareImplicitDestructor(ClassDecl); | 
 | 5922 |   } | 
| Douglas Gregor | 396b7cd | 2008-11-03 17:51:48 +0000 | [diff] [blame] | 5923 | } | 
 | 5924 |  | 
| Francois Pichet | 8387e2a | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 5925 | void Sema::ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D) { | 
 | 5926 |   if (!D) | 
 | 5927 |     return; | 
 | 5928 |  | 
 | 5929 |   int NumParamList = D->getNumTemplateParameterLists(); | 
 | 5930 |   for (int i = 0; i < NumParamList; i++) { | 
 | 5931 |     TemplateParameterList* Params = D->getTemplateParameterList(i); | 
 | 5932 |     for (TemplateParameterList::iterator Param = Params->begin(), | 
 | 5933 |                                       ParamEnd = Params->end(); | 
 | 5934 |           Param != ParamEnd; ++Param) { | 
 | 5935 |       NamedDecl *Named = cast<NamedDecl>(*Param); | 
 | 5936 |       if (Named->getDeclName()) { | 
 | 5937 |         S->AddDecl(Named); | 
 | 5938 |         IdResolver.AddDecl(Named); | 
 | 5939 |       } | 
 | 5940 |     } | 
 | 5941 |   } | 
 | 5942 | } | 
 | 5943 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5944 | void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) { | 
| Douglas Gregor | 1cdcc57 | 2009-09-10 00:12:48 +0000 | [diff] [blame] | 5945 |   if (!D) | 
 | 5946 |     return; | 
 | 5947 |    | 
 | 5948 |   TemplateParameterList *Params = 0; | 
 | 5949 |   if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) | 
 | 5950 |     Params = Template->getTemplateParameters(); | 
 | 5951 |   else if (ClassTemplatePartialSpecializationDecl *PartialSpec | 
 | 5952 |            = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) | 
 | 5953 |     Params = PartialSpec->getTemplateParameters(); | 
 | 5954 |   else | 
| Douglas Gregor | 6569d68 | 2009-05-27 23:11:45 +0000 | [diff] [blame] | 5955 |     return; | 
 | 5956 |  | 
| Douglas Gregor | 6569d68 | 2009-05-27 23:11:45 +0000 | [diff] [blame] | 5957 |   for (TemplateParameterList::iterator Param = Params->begin(), | 
 | 5958 |                                     ParamEnd = Params->end(); | 
 | 5959 |        Param != ParamEnd; ++Param) { | 
 | 5960 |     NamedDecl *Named = cast<NamedDecl>(*Param); | 
 | 5961 |     if (Named->getDeclName()) { | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5962 |       S->AddDecl(Named); | 
| Douglas Gregor | 6569d68 | 2009-05-27 23:11:45 +0000 | [diff] [blame] | 5963 |       IdResolver.AddDecl(Named); | 
 | 5964 |     } | 
 | 5965 |   } | 
 | 5966 | } | 
 | 5967 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5968 | void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, Decl *RecordD) { | 
| John McCall | 7a1dc56 | 2009-12-19 10:49:29 +0000 | [diff] [blame] | 5969 |   if (!RecordD) return; | 
 | 5970 |   AdjustDeclIfTemplate(RecordD); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5971 |   CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordD); | 
| John McCall | 7a1dc56 | 2009-12-19 10:49:29 +0000 | [diff] [blame] | 5972 |   PushDeclContext(S, Record); | 
 | 5973 | } | 
 | 5974 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5975 | void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *RecordD) { | 
| John McCall | 7a1dc56 | 2009-12-19 10:49:29 +0000 | [diff] [blame] | 5976 |   if (!RecordD) return; | 
 | 5977 |   PopDeclContext(); | 
 | 5978 | } | 
 | 5979 |  | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 5980 | /// ActOnStartDelayedCXXMethodDeclaration - We have completed | 
 | 5981 | /// parsing a top-level (non-nested) C++ class, and we are now | 
 | 5982 | /// parsing those parts of the given Method declaration that could | 
 | 5983 | /// not be parsed earlier (C++ [class.mem]p2), such as default | 
 | 5984 | /// arguments. This action should enter the scope of the given | 
 | 5985 | /// Method declaration as if we had just parsed the qualified method | 
 | 5986 | /// name. However, it should not bring the parameters into scope; | 
 | 5987 | /// that will be performed by ActOnDelayedCXXMethodParameter. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5988 | void Sema::ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *MethodD) { | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 5989 | } | 
 | 5990 |  | 
 | 5991 | /// ActOnDelayedCXXMethodParameter - We've already started a delayed | 
 | 5992 | /// C++ method declaration. We're (re-)introducing the given | 
 | 5993 | /// function parameter into scope for use in parsing later parts of | 
 | 5994 | /// the method declaration. For example, we could see an | 
 | 5995 | /// ActOnParamDefaultArgument event for this parameter. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5996 | void Sema::ActOnDelayedCXXMethodParameter(Scope *S, Decl *ParamD) { | 
| Douglas Gregor | 4c4f7cb | 2009-06-22 23:20:33 +0000 | [diff] [blame] | 5997 |   if (!ParamD) | 
 | 5998 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5999 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6000 |   ParmVarDecl *Param = cast<ParmVarDecl>(ParamD); | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 6001 |  | 
 | 6002 |   // If this parameter has an unparsed default argument, clear it out | 
 | 6003 |   // to make way for the parsed default argument. | 
 | 6004 |   if (Param->hasUnparsedDefaultArg()) | 
 | 6005 |     Param->setDefaultArg(0); | 
 | 6006 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6007 |   S->AddDecl(Param); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 6008 |   if (Param->getDeclName()) | 
 | 6009 |     IdResolver.AddDecl(Param); | 
 | 6010 | } | 
 | 6011 |  | 
 | 6012 | /// ActOnFinishDelayedCXXMethodDeclaration - We have finished | 
 | 6013 | /// processing the delayed method declaration for Method. The method | 
 | 6014 | /// declaration is now considered finished. There may be a separate | 
 | 6015 | /// ActOnStartOfFunctionDef action later (not necessarily | 
 | 6016 | /// immediately!) for this method, if it was also defined inside the | 
 | 6017 | /// class body. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6018 | void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *MethodD) { | 
| Douglas Gregor | 4c4f7cb | 2009-06-22 23:20:33 +0000 | [diff] [blame] | 6019 |   if (!MethodD) | 
 | 6020 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6021 |  | 
| Douglas Gregor | efd5bda | 2009-08-24 11:57:43 +0000 | [diff] [blame] | 6022 |   AdjustDeclIfTemplate(MethodD); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6023 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6024 |   FunctionDecl *Method = cast<FunctionDecl>(MethodD); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 6025 |  | 
 | 6026 |   // Now that we have our default arguments, check the constructor | 
 | 6027 |   // again. It could produce additional diagnostics or affect whether | 
 | 6028 |   // the class has implicitly-declared destructors, among other | 
 | 6029 |   // things. | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6030 |   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Method)) | 
 | 6031 |     CheckConstructor(Constructor); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 6032 |  | 
 | 6033 |   // Check the default arguments, which we may have added. | 
 | 6034 |   if (!Method->isInvalidDecl()) | 
 | 6035 |     CheckCXXDefaultArguments(Method); | 
 | 6036 | } | 
 | 6037 |  | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6038 | /// CheckConstructorDeclarator - Called by ActOnDeclarator to check | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 6039 | /// the well-formedness of the constructor declarator @p D with type @p | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6040 | /// R. If there are any errors in the declarator, this routine will | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6041 | /// emit diagnostics and set the invalid bit to true.  In any case, the type | 
 | 6042 | /// will be updated to reflect a well-formed type for the constructor and | 
 | 6043 | /// returned. | 
 | 6044 | QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R, | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 6045 |                                           StorageClass &SC) { | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6046 |   bool isVirtual = D.getDeclSpec().isVirtualSpecified(); | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6047 |  | 
 | 6048 |   // C++ [class.ctor]p3: | 
 | 6049 |   //   A constructor shall not be virtual (10.3) or static (9.4). A | 
 | 6050 |   //   constructor can be invoked for a const, volatile or const | 
 | 6051 |   //   volatile object. A constructor shall not be declared const, | 
 | 6052 |   //   volatile, or const volatile (9.3.2). | 
 | 6053 |   if (isVirtual) { | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6054 |     if (!D.isInvalidType()) | 
 | 6055 |       Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be) | 
 | 6056 |         << "virtual" << SourceRange(D.getDeclSpec().getVirtualSpecLoc()) | 
 | 6057 |         << SourceRange(D.getIdentifierLoc()); | 
 | 6058 |     D.setInvalidType(); | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6059 |   } | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 6060 |   if (SC == SC_Static) { | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6061 |     if (!D.isInvalidType()) | 
 | 6062 |       Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be) | 
 | 6063 |         << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc()) | 
 | 6064 |         << SourceRange(D.getIdentifierLoc()); | 
 | 6065 |     D.setInvalidType(); | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 6066 |     SC = SC_None; | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6067 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6068 |  | 
| Abramo Bagnara | 075f8f1 | 2010-12-10 16:29:40 +0000 | [diff] [blame] | 6069 |   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6070 |   if (FTI.TypeQuals != 0) { | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 6071 |     if (FTI.TypeQuals & Qualifiers::Const) | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 6072 |       Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) | 
 | 6073 |         << "const" << SourceRange(D.getIdentifierLoc()); | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 6074 |     if (FTI.TypeQuals & Qualifiers::Volatile) | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 6075 |       Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) | 
 | 6076 |         << "volatile" << SourceRange(D.getIdentifierLoc()); | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 6077 |     if (FTI.TypeQuals & Qualifiers::Restrict) | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 6078 |       Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) | 
 | 6079 |         << "restrict" << SourceRange(D.getIdentifierLoc()); | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 6080 |     D.setInvalidType(); | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6081 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6082 |  | 
| Douglas Gregor | c938c16 | 2011-01-26 05:01:58 +0000 | [diff] [blame] | 6083 |   // C++0x [class.ctor]p4: | 
 | 6084 |   //   A constructor shall not be declared with a ref-qualifier. | 
 | 6085 |   if (FTI.hasRefQualifier()) { | 
 | 6086 |     Diag(FTI.getRefQualifierLoc(), diag::err_ref_qualifier_constructor) | 
 | 6087 |       << FTI.RefQualifierIsLValueRef  | 
 | 6088 |       << FixItHint::CreateRemoval(FTI.getRefQualifierLoc()); | 
 | 6089 |     D.setInvalidType(); | 
 | 6090 |   } | 
 | 6091 |    | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6092 |   // Rebuild the function type "R" without any type qualifiers (in | 
 | 6093 |   // case any of the errors above fired) and with "void" as the | 
| Douglas Gregor | d92ec47 | 2010-07-01 05:10:53 +0000 | [diff] [blame] | 6094 |   // return type, since constructors don't have return types. | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 6095 |   const FunctionProtoType *Proto = R->getAs<FunctionProtoType>(); | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 6096 |   if (Proto->getResultType() == Context.VoidTy && !D.isInvalidType()) | 
 | 6097 |     return R; | 
 | 6098 |  | 
 | 6099 |   FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); | 
 | 6100 |   EPI.TypeQuals = 0; | 
| Douglas Gregor | c938c16 | 2011-01-26 05:01:58 +0000 | [diff] [blame] | 6101 |   EPI.RefQualifier = RQ_None; | 
 | 6102 |    | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 6103 |   return Context.getFunctionType(Context.VoidTy, Proto->getArgTypes(), EPI); | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6104 | } | 
 | 6105 |  | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 6106 | /// CheckConstructor - Checks a fully-formed constructor for | 
 | 6107 | /// well-formedness, issuing any diagnostics required. Returns true if | 
 | 6108 | /// the constructor declarator is invalid. | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6109 | void Sema::CheckConstructor(CXXConstructorDecl *Constructor) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6110 |   CXXRecordDecl *ClassDecl | 
| Douglas Gregor | 3329756 | 2009-03-27 04:38:56 +0000 | [diff] [blame] | 6111 |     = dyn_cast<CXXRecordDecl>(Constructor->getDeclContext()); | 
 | 6112 |   if (!ClassDecl) | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6113 |     return Constructor->setInvalidDecl(); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 6114 |  | 
 | 6115 |   // C++ [class.copy]p3: | 
 | 6116 |   //   A declaration of a constructor for a class X is ill-formed if | 
 | 6117 |   //   its first parameter is of type (optionally cv-qualified) X and | 
 | 6118 |   //   either there are no other parameters or else all other | 
 | 6119 |   //   parameters have default arguments. | 
| Douglas Gregor | 3329756 | 2009-03-27 04:38:56 +0000 | [diff] [blame] | 6120 |   if (!Constructor->isInvalidDecl() && | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6121 |       ((Constructor->getNumParams() == 1) || | 
 | 6122 |        (Constructor->getNumParams() > 1 && | 
| Douglas Gregor | 66724ea | 2009-11-14 01:20:54 +0000 | [diff] [blame] | 6123 |         Constructor->getParamDecl(1)->hasDefaultArg())) && | 
 | 6124 |       Constructor->getTemplateSpecializationKind() | 
 | 6125 |                                               != TSK_ImplicitInstantiation) { | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 6126 |     QualType ParamType = Constructor->getParamDecl(0)->getType(); | 
 | 6127 |     QualType ClassTy = Context.getTagDeclType(ClassDecl); | 
 | 6128 |     if (Context.getCanonicalType(ParamType).getUnqualifiedType() == ClassTy) { | 
| Douglas Gregor | a3a8351 | 2009-04-01 23:51:29 +0000 | [diff] [blame] | 6129 |       SourceLocation ParamLoc = Constructor->getParamDecl(0)->getLocation(); | 
| Douglas Gregor | aeb4a28 | 2010-05-27 21:28:21 +0000 | [diff] [blame] | 6130 |       const char *ConstRef  | 
 | 6131 |         = Constructor->getParamDecl(0)->getIdentifier() ? "const &"  | 
 | 6132 |                                                         : " const &"; | 
| Douglas Gregor | a3a8351 | 2009-04-01 23:51:29 +0000 | [diff] [blame] | 6133 |       Diag(ParamLoc, diag::err_constructor_byvalue_arg) | 
| Douglas Gregor | aeb4a28 | 2010-05-27 21:28:21 +0000 | [diff] [blame] | 6134 |         << FixItHint::CreateInsertion(ParamLoc, ConstRef); | 
| Douglas Gregor | 66724ea | 2009-11-14 01:20:54 +0000 | [diff] [blame] | 6135 |  | 
 | 6136 |       // FIXME: Rather that making the constructor invalid, we should endeavor | 
 | 6137 |       // to fix the type. | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6138 |       Constructor->setInvalidDecl(); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 6139 |     } | 
 | 6140 |   } | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 6141 | } | 
 | 6142 |  | 
| John McCall | 1544282 | 2010-08-04 01:04:25 +0000 | [diff] [blame] | 6143 | /// CheckDestructor - Checks a fully-formed destructor definition for | 
 | 6144 | /// well-formedness, issuing any diagnostics required.  Returns true | 
 | 6145 | /// on error. | 
| Anders Carlsson | 5ec02ae | 2009-12-02 17:15:43 +0000 | [diff] [blame] | 6146 | bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) { | 
| Anders Carlsson | 6d70139 | 2009-11-15 22:49:34 +0000 | [diff] [blame] | 6147 |   CXXRecordDecl *RD = Destructor->getParent(); | 
 | 6148 |    | 
| Peter Collingbourne | f51cfb8 | 2013-05-20 14:12:25 +0000 | [diff] [blame] | 6149 |   if (!Destructor->getOperatorDelete() && Destructor->isVirtual()) { | 
| Anders Carlsson | 6d70139 | 2009-11-15 22:49:34 +0000 | [diff] [blame] | 6150 |     SourceLocation Loc; | 
 | 6151 |      | 
 | 6152 |     if (!Destructor->isImplicit()) | 
 | 6153 |       Loc = Destructor->getLocation(); | 
 | 6154 |     else | 
 | 6155 |       Loc = RD->getLocation(); | 
 | 6156 |      | 
 | 6157 |     // If we have a virtual destructor, look up the deallocation function | 
 | 6158 |     FunctionDecl *OperatorDelete = 0; | 
 | 6159 |     DeclarationName Name =  | 
 | 6160 |     Context.DeclarationNames.getCXXOperatorName(OO_Delete); | 
| Anders Carlsson | 5ec02ae | 2009-12-02 17:15:43 +0000 | [diff] [blame] | 6161 |     if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete)) | 
| Anders Carlsson | 3790980 | 2009-11-30 21:24:50 +0000 | [diff] [blame] | 6162 |       return true; | 
| John McCall | 5efd91a | 2010-07-03 18:33:00 +0000 | [diff] [blame] | 6163 |  | 
| Eli Friedman | 5f2987c | 2012-02-02 03:46:19 +0000 | [diff] [blame] | 6164 |     MarkFunctionReferenced(Loc, OperatorDelete); | 
| Anders Carlsson | 3790980 | 2009-11-30 21:24:50 +0000 | [diff] [blame] | 6165 |      | 
 | 6166 |     Destructor->setOperatorDelete(OperatorDelete); | 
| Anders Carlsson | 6d70139 | 2009-11-15 22:49:34 +0000 | [diff] [blame] | 6167 |   } | 
| Anders Carlsson | 3790980 | 2009-11-30 21:24:50 +0000 | [diff] [blame] | 6168 |    | 
 | 6169 |   return false; | 
| Anders Carlsson | 6d70139 | 2009-11-15 22:49:34 +0000 | [diff] [blame] | 6170 | } | 
 | 6171 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6172 | static inline bool | 
| Anders Carlsson | 7786d1c | 2009-04-30 23:18:11 +0000 | [diff] [blame] | 6173 | FTIHasSingleVoidArgument(DeclaratorChunk::FunctionTypeInfo &FTI) { | 
 | 6174 |   return (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 && | 
 | 6175 |           FTI.ArgInfo[0].Param && | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6176 |           cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()); | 
| Anders Carlsson | 7786d1c | 2009-04-30 23:18:11 +0000 | [diff] [blame] | 6177 | } | 
 | 6178 |  | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6179 | /// CheckDestructorDeclarator - Called by ActOnDeclarator to check | 
 | 6180 | /// the well-formednes of the destructor declarator @p D with type @p | 
 | 6181 | /// R. If there are any errors in the declarator, this routine will | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6182 | /// emit diagnostics and set the declarator to invalid.  Even if this happens, | 
 | 6183 | /// will be updated to reflect a well-formed type for the destructor and | 
 | 6184 | /// returned. | 
| Douglas Gregor | d92ec47 | 2010-07-01 05:10:53 +0000 | [diff] [blame] | 6185 | QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R, | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 6186 |                                          StorageClass& SC) { | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6187 |   // C++ [class.dtor]p1: | 
 | 6188 |   //   [...] A typedef-name that names a class is a class-name | 
 | 6189 |   //   (7.1.3); however, a typedef-name that names a class shall not | 
 | 6190 |   //   be used as the identifier in the declarator for a destructor | 
 | 6191 |   //   declaration. | 
| Douglas Gregor | 3f9a056 | 2009-11-03 01:35:08 +0000 | [diff] [blame] | 6192 |   QualType DeclaratorType = GetTypeFromParser(D.getName().DestructorName); | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 6193 |   if (const TypedefType *TT = DeclaratorType->getAs<TypedefType>()) | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6194 |     Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name) | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 6195 |       << DeclaratorType << isa<TypeAliasDecl>(TT->getDecl()); | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 6196 |   else if (const TemplateSpecializationType *TST = | 
 | 6197 |              DeclaratorType->getAs<TemplateSpecializationType>()) | 
 | 6198 |     if (TST->isTypeAlias()) | 
 | 6199 |       Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name) | 
 | 6200 |         << DeclaratorType << 1; | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6201 |  | 
 | 6202 |   // C++ [class.dtor]p2: | 
 | 6203 |   //   A destructor is used to destroy objects of its class type. A | 
 | 6204 |   //   destructor takes no parameters, and no return type can be | 
 | 6205 |   //   specified for it (not even void). The address of a destructor | 
 | 6206 |   //   shall not be taken. A destructor shall not be static. A | 
 | 6207 |   //   destructor can be invoked for a const, volatile or const | 
 | 6208 |   //   volatile object. A destructor shall not be declared const, | 
 | 6209 |   //   volatile or const volatile (9.3.2). | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 6210 |   if (SC == SC_Static) { | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6211 |     if (!D.isInvalidType()) | 
 | 6212 |       Diag(D.getIdentifierLoc(), diag::err_destructor_cannot_be) | 
 | 6213 |         << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc()) | 
| Douglas Gregor | d92ec47 | 2010-07-01 05:10:53 +0000 | [diff] [blame] | 6214 |         << SourceRange(D.getIdentifierLoc()) | 
 | 6215 |         << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc()); | 
 | 6216 |      | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 6217 |     SC = SC_None; | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6218 |   } | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6219 |   if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) { | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6220 |     // Destructors don't have return types, but the parser will | 
 | 6221 |     // happily parse something like: | 
 | 6222 |     // | 
 | 6223 |     //   class X { | 
 | 6224 |     //     float ~X(); | 
 | 6225 |     //   }; | 
 | 6226 |     // | 
 | 6227 |     // The return type will be eliminated later. | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 6228 |     Diag(D.getIdentifierLoc(), diag::err_destructor_return_type) | 
 | 6229 |       << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc()) | 
 | 6230 |       << SourceRange(D.getIdentifierLoc()); | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6231 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6232 |  | 
| Abramo Bagnara | 075f8f1 | 2010-12-10 16:29:40 +0000 | [diff] [blame] | 6233 |   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6234 |   if (FTI.TypeQuals != 0 && !D.isInvalidType()) { | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 6235 |     if (FTI.TypeQuals & Qualifiers::Const) | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 6236 |       Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) | 
 | 6237 |         << "const" << SourceRange(D.getIdentifierLoc()); | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 6238 |     if (FTI.TypeQuals & Qualifiers::Volatile) | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 6239 |       Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) | 
 | 6240 |         << "volatile" << SourceRange(D.getIdentifierLoc()); | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 6241 |     if (FTI.TypeQuals & Qualifiers::Restrict) | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 6242 |       Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) | 
 | 6243 |         << "restrict" << SourceRange(D.getIdentifierLoc()); | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6244 |     D.setInvalidType(); | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6245 |   } | 
 | 6246 |  | 
| Douglas Gregor | c938c16 | 2011-01-26 05:01:58 +0000 | [diff] [blame] | 6247 |   // C++0x [class.dtor]p2: | 
 | 6248 |   //   A destructor shall not be declared with a ref-qualifier. | 
 | 6249 |   if (FTI.hasRefQualifier()) { | 
 | 6250 |     Diag(FTI.getRefQualifierLoc(), diag::err_ref_qualifier_destructor) | 
 | 6251 |       << FTI.RefQualifierIsLValueRef | 
 | 6252 |       << FixItHint::CreateRemoval(FTI.getRefQualifierLoc()); | 
 | 6253 |     D.setInvalidType(); | 
 | 6254 |   } | 
 | 6255 |    | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6256 |   // Make sure we don't have any parameters. | 
| Anders Carlsson | 7786d1c | 2009-04-30 23:18:11 +0000 | [diff] [blame] | 6257 |   if (FTI.NumArgs > 0 && !FTIHasSingleVoidArgument(FTI)) { | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6258 |     Diag(D.getIdentifierLoc(), diag::err_destructor_with_params); | 
 | 6259 |  | 
 | 6260 |     // Delete the parameters. | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6261 |     FTI.freeArgs(); | 
 | 6262 |     D.setInvalidType(); | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6263 |   } | 
 | 6264 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6265 |   // Make sure the destructor isn't variadic. | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6266 |   if (FTI.isVariadic) { | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6267 |     Diag(D.getIdentifierLoc(), diag::err_destructor_variadic); | 
| Chris Lattner | 6540180 | 2009-04-25 08:28:21 +0000 | [diff] [blame] | 6268 |     D.setInvalidType(); | 
 | 6269 |   } | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6270 |  | 
 | 6271 |   // Rebuild the function type "R" without any type qualifiers or | 
 | 6272 |   // parameters (in case any of the errors above fired) and with | 
 | 6273 |   // "void" as the return type, since destructors don't have return | 
| Douglas Gregor | d92ec47 | 2010-07-01 05:10:53 +0000 | [diff] [blame] | 6274 |   // types.  | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 6275 |   if (!D.isInvalidType()) | 
 | 6276 |     return R; | 
 | 6277 |  | 
| Douglas Gregor | d92ec47 | 2010-07-01 05:10:53 +0000 | [diff] [blame] | 6278 |   const FunctionProtoType *Proto = R->getAs<FunctionProtoType>(); | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 6279 |   FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); | 
 | 6280 |   EPI.Variadic = false; | 
 | 6281 |   EPI.TypeQuals = 0; | 
| Douglas Gregor | c938c16 | 2011-01-26 05:01:58 +0000 | [diff] [blame] | 6282 |   EPI.RefQualifier = RQ_None; | 
| Dmitri Gribenko | 5543169 | 2013-05-05 00:41:58 +0000 | [diff] [blame] | 6283 |   return Context.getFunctionType(Context.VoidTy, None, EPI); | 
| Douglas Gregor | 42a552f | 2008-11-05 20:51:48 +0000 | [diff] [blame] | 6284 | } | 
 | 6285 |  | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6286 | /// CheckConversionDeclarator - Called by ActOnDeclarator to check the | 
 | 6287 | /// well-formednes of the conversion function declarator @p D with | 
 | 6288 | /// type @p R. If there are any errors in the declarator, this routine | 
 | 6289 | /// will emit diagnostics and return true. Otherwise, it will return | 
 | 6290 | /// false. Either way, the type @p R will be updated to reflect a | 
 | 6291 | /// well-formed type for the conversion operator. | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6292 | void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 6293 |                                      StorageClass& SC) { | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6294 |   // C++ [class.conv.fct]p1: | 
 | 6295 |   //   Neither parameter types nor return type can be specified. The | 
| Eli Friedman | 33a3138 | 2009-08-05 19:21:58 +0000 | [diff] [blame] | 6296 |   //   type of a conversion function (8.3.5) is "function taking no | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6297 |   //   parameter returning conversion-type-id." | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 6298 |   if (SC == SC_Static) { | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6299 |     if (!D.isInvalidType()) | 
 | 6300 |       Diag(D.getIdentifierLoc(), diag::err_conv_function_not_member) | 
| Eli Friedman | 4cde94a | 2013-06-20 20:58:02 +0000 | [diff] [blame] | 6301 |         << SourceRange(D.getDeclSpec().getStorageClassSpecLoc()) | 
 | 6302 |         << D.getName().getSourceRange(); | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6303 |     D.setInvalidType(); | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 6304 |     SC = SC_None; | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6305 |   } | 
| John McCall | a3f8137 | 2010-04-13 00:04:31 +0000 | [diff] [blame] | 6306 |  | 
 | 6307 |   QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId); | 
 | 6308 |  | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6309 |   if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) { | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6310 |     // Conversion functions don't have return types, but the parser will | 
 | 6311 |     // happily parse something like: | 
 | 6312 |     // | 
 | 6313 |     //   class X { | 
 | 6314 |     //     float operator bool(); | 
 | 6315 |     //   }; | 
 | 6316 |     // | 
 | 6317 |     // The return type will be changed later anyway. | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 6318 |     Diag(D.getIdentifierLoc(), diag::err_conv_function_return_type) | 
 | 6319 |       << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc()) | 
 | 6320 |       << SourceRange(D.getIdentifierLoc()); | 
| John McCall | a3f8137 | 2010-04-13 00:04:31 +0000 | [diff] [blame] | 6321 |     D.setInvalidType(); | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6322 |   } | 
 | 6323 |  | 
| John McCall | a3f8137 | 2010-04-13 00:04:31 +0000 | [diff] [blame] | 6324 |   const FunctionProtoType *Proto = R->getAs<FunctionProtoType>(); | 
 | 6325 |  | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6326 |   // Make sure we don't have any parameters. | 
| John McCall | a3f8137 | 2010-04-13 00:04:31 +0000 | [diff] [blame] | 6327 |   if (Proto->getNumArgs() > 0) { | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6328 |     Diag(D.getIdentifierLoc(), diag::err_conv_function_with_params); | 
 | 6329 |  | 
 | 6330 |     // Delete the parameters. | 
| Abramo Bagnara | 075f8f1 | 2010-12-10 16:29:40 +0000 | [diff] [blame] | 6331 |     D.getFunctionTypeInfo().freeArgs(); | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6332 |     D.setInvalidType(); | 
| John McCall | a3f8137 | 2010-04-13 00:04:31 +0000 | [diff] [blame] | 6333 |   } else if (Proto->isVariadic()) { | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6334 |     Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic); | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6335 |     D.setInvalidType(); | 
 | 6336 |   } | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6337 |  | 
| John McCall | a3f8137 | 2010-04-13 00:04:31 +0000 | [diff] [blame] | 6338 |   // Diagnose "&operator bool()" and other such nonsense.  This | 
 | 6339 |   // is actually a gcc extension which we don't support. | 
 | 6340 |   if (Proto->getResultType() != ConvType) { | 
 | 6341 |     Diag(D.getIdentifierLoc(), diag::err_conv_function_with_complex_decl) | 
 | 6342 |       << Proto->getResultType(); | 
 | 6343 |     D.setInvalidType(); | 
 | 6344 |     ConvType = Proto->getResultType(); | 
 | 6345 |   } | 
 | 6346 |  | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6347 |   // C++ [class.conv.fct]p4: | 
 | 6348 |   //   The conversion-type-id shall not represent a function type nor | 
 | 6349 |   //   an array type. | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6350 |   if (ConvType->isArrayType()) { | 
 | 6351 |     Diag(D.getIdentifierLoc(), diag::err_conv_function_to_array); | 
 | 6352 |     ConvType = Context.getPointerType(ConvType); | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6353 |     D.setInvalidType(); | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6354 |   } else if (ConvType->isFunctionType()) { | 
 | 6355 |     Diag(D.getIdentifierLoc(), diag::err_conv_function_to_function); | 
 | 6356 |     ConvType = Context.getPointerType(ConvType); | 
| Chris Lattner | 6e47501 | 2009-04-25 08:35:12 +0000 | [diff] [blame] | 6357 |     D.setInvalidType(); | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6358 |   } | 
 | 6359 |  | 
 | 6360 |   // Rebuild the function type "R" without any parameters (in case any | 
 | 6361 |   // of the errors above fired) and with the conversion type as the | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6362 |   // return type. | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 6363 |   if (D.isInvalidType()) | 
| Dmitri Gribenko | 5543169 | 2013-05-05 00:41:58 +0000 | [diff] [blame] | 6364 |     R = Context.getFunctionType(ConvType, None, Proto->getExtProtoInfo()); | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6365 |  | 
| Douglas Gregor | 09f41cf | 2009-01-14 15:45:31 +0000 | [diff] [blame] | 6366 |   // C++0x explicit conversion operators. | 
| Richard Smith | ebaf0e6 | 2011-10-18 20:49:44 +0000 | [diff] [blame] | 6367 |   if (D.getDeclSpec().isExplicitSpecified()) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6368 |     Diag(D.getDeclSpec().getExplicitSpecLoc(), | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 6369 |          getLangOpts().CPlusPlus11 ? | 
| Richard Smith | ebaf0e6 | 2011-10-18 20:49:44 +0000 | [diff] [blame] | 6370 |            diag::warn_cxx98_compat_explicit_conversion_functions : | 
 | 6371 |            diag::ext_explicit_conversion_functions) | 
| Douglas Gregor | 09f41cf | 2009-01-14 15:45:31 +0000 | [diff] [blame] | 6372 |       << SourceRange(D.getDeclSpec().getExplicitSpecLoc()); | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6373 | } | 
 | 6374 |  | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6375 | /// ActOnConversionDeclarator - Called by ActOnDeclarator to complete | 
 | 6376 | /// the declaration of the given C++ conversion function. This routine | 
 | 6377 | /// is responsible for recording the conversion function in the C++ | 
 | 6378 | /// class, if possible. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6379 | Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) { | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6380 |   assert(Conversion && "Expected to receive a conversion function declaration"); | 
 | 6381 |  | 
| Douglas Gregor | 9d35097 | 2008-12-12 08:25:50 +0000 | [diff] [blame] | 6382 |   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Conversion->getDeclContext()); | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6383 |  | 
 | 6384 |   // Make sure we aren't redeclaring the conversion function. | 
 | 6385 |   QualType ConvType = Context.getCanonicalType(Conversion->getConversionType()); | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6386 |  | 
 | 6387 |   // C++ [class.conv.fct]p1: | 
 | 6388 |   //   [...] A conversion function is never used to convert a | 
 | 6389 |   //   (possibly cv-qualified) object to the (possibly cv-qualified) | 
 | 6390 |   //   same object type (or a reference to it), to a (possibly | 
 | 6391 |   //   cv-qualified) base class of that type (or a reference to it), | 
 | 6392 |   //   or to (possibly cv-qualified) void. | 
| Mike Stump | 390b4cc | 2009-05-16 07:39:55 +0000 | [diff] [blame] | 6393 |   // FIXME: Suppress this warning if the conversion function ends up being a | 
 | 6394 |   // virtual function that overrides a virtual function in a base class. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6395 |   QualType ClassType | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6396 |     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl)); | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 6397 |   if (const ReferenceType *ConvTypeRef = ConvType->getAs<ReferenceType>()) | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6398 |     ConvType = ConvTypeRef->getPointeeType(); | 
| Douglas Gregor | da0fd9a | 2010-09-12 07:22:28 +0000 | [diff] [blame] | 6399 |   if (Conversion->getTemplateSpecializationKind() != TSK_Undeclared && | 
 | 6400 |       Conversion->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) | 
| Douglas Gregor | 1034170 | 2010-09-13 16:44:26 +0000 | [diff] [blame] | 6401 |     /* Suppress diagnostics for instantiations. */; | 
| Douglas Gregor | da0fd9a | 2010-09-12 07:22:28 +0000 | [diff] [blame] | 6402 |   else if (ConvType->isRecordType()) { | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6403 |     ConvType = Context.getCanonicalType(ConvType).getUnqualifiedType(); | 
 | 6404 |     if (ConvType == ClassType) | 
| Chris Lattner | 5dc266a | 2008-11-20 06:13:02 +0000 | [diff] [blame] | 6405 |       Diag(Conversion->getLocation(), diag::warn_conv_to_self_not_used) | 
| Chris Lattner | d162584 | 2008-11-24 06:25:27 +0000 | [diff] [blame] | 6406 |         << ClassType; | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6407 |     else if (IsDerivedFrom(ClassType, ConvType)) | 
| Chris Lattner | 5dc266a | 2008-11-20 06:13:02 +0000 | [diff] [blame] | 6408 |       Diag(Conversion->getLocation(), diag::warn_conv_to_base_not_used) | 
| Chris Lattner | d162584 | 2008-11-24 06:25:27 +0000 | [diff] [blame] | 6409 |         <<  ClassType << ConvType; | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6410 |   } else if (ConvType->isVoidType()) { | 
| Chris Lattner | 5dc266a | 2008-11-20 06:13:02 +0000 | [diff] [blame] | 6411 |     Diag(Conversion->getLocation(), diag::warn_conv_to_void_not_used) | 
| Chris Lattner | d162584 | 2008-11-24 06:25:27 +0000 | [diff] [blame] | 6412 |       << ClassType << ConvType; | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6413 |   } | 
 | 6414 |  | 
| Douglas Gregor | e80622f | 2010-09-29 04:25:11 +0000 | [diff] [blame] | 6415 |   if (FunctionTemplateDecl *ConversionTemplate | 
 | 6416 |                                 = Conversion->getDescribedFunctionTemplate()) | 
 | 6417 |     return ConversionTemplate; | 
 | 6418 |    | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6419 |   return Conversion; | 
| Douglas Gregor | 2f1bc52 | 2008-11-07 20:08:42 +0000 | [diff] [blame] | 6420 | } | 
 | 6421 |  | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6422 | //===----------------------------------------------------------------------===// | 
 | 6423 | // Namespace Handling | 
 | 6424 | //===----------------------------------------------------------------------===// | 
 | 6425 |  | 
| Richard Smith | d1a55a6 | 2012-10-04 22:13:39 +0000 | [diff] [blame] | 6426 | /// \brief Diagnose a mismatch in 'inline' qualifiers when a namespace is | 
 | 6427 | /// reopened. | 
 | 6428 | static void DiagnoseNamespaceInlineMismatch(Sema &S, SourceLocation KeywordLoc, | 
 | 6429 |                                             SourceLocation Loc, | 
 | 6430 |                                             IdentifierInfo *II, bool *IsInline, | 
 | 6431 |                                             NamespaceDecl *PrevNS) { | 
 | 6432 |   assert(*IsInline != PrevNS->isInline()); | 
| John McCall | ea31864 | 2010-08-26 09:15:37 +0000 | [diff] [blame] | 6433 |  | 
| Richard Smith | c969e6a | 2012-10-05 01:46:25 +0000 | [diff] [blame] | 6434 |   // HACK: Work around a bug in libstdc++4.6's <atomic>, where | 
 | 6435 |   // std::__atomic[0,1,2] are defined as non-inline namespaces, then reopened as | 
 | 6436 |   // inline namespaces, with the intention of bringing names into namespace std. | 
 | 6437 |   // | 
 | 6438 |   // We support this just well enough to get that case working; this is not | 
 | 6439 |   // sufficient to support reopening namespaces as inline in general. | 
| Richard Smith | d1a55a6 | 2012-10-04 22:13:39 +0000 | [diff] [blame] | 6440 |   if (*IsInline && II && II->getName().startswith("__atomic") && | 
 | 6441 |       S.getSourceManager().isInSystemHeader(Loc)) { | 
| Richard Smith | c969e6a | 2012-10-05 01:46:25 +0000 | [diff] [blame] | 6442 |     // Mark all prior declarations of the namespace as inline. | 
| Richard Smith | d1a55a6 | 2012-10-04 22:13:39 +0000 | [diff] [blame] | 6443 |     for (NamespaceDecl *NS = PrevNS->getMostRecentDecl(); NS; | 
 | 6444 |          NS = NS->getPreviousDecl()) | 
 | 6445 |       NS->setInline(*IsInline); | 
 | 6446 |     // Patch up the lookup table for the containing namespace. This isn't really | 
 | 6447 |     // correct, but it's good enough for this particular case. | 
 | 6448 |     for (DeclContext::decl_iterator I = PrevNS->decls_begin(), | 
 | 6449 |                                     E = PrevNS->decls_end(); I != E; ++I) | 
 | 6450 |       if (NamedDecl *ND = dyn_cast<NamedDecl>(*I)) | 
 | 6451 |         PrevNS->getParent()->makeDeclVisibleInContext(ND); | 
 | 6452 |     return; | 
 | 6453 |   } | 
 | 6454 |  | 
 | 6455 |   if (PrevNS->isInline()) | 
 | 6456 |     // The user probably just forgot the 'inline', so suggest that it | 
 | 6457 |     // be added back. | 
 | 6458 |     S.Diag(Loc, diag::warn_inline_namespace_reopened_noninline) | 
 | 6459 |       << FixItHint::CreateInsertion(KeywordLoc, "inline "); | 
 | 6460 |   else | 
 | 6461 |     S.Diag(Loc, diag::err_inline_namespace_mismatch) | 
 | 6462 |       << IsInline; | 
 | 6463 |  | 
 | 6464 |   S.Diag(PrevNS->getLocation(), diag::note_previous_definition); | 
 | 6465 |   *IsInline = PrevNS->isInline(); | 
 | 6466 | } | 
| John McCall | ea31864 | 2010-08-26 09:15:37 +0000 | [diff] [blame] | 6467 |  | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6468 | /// ActOnStartNamespaceDef - This is called at the start of a namespace | 
 | 6469 | /// definition. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6470 | Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, | 
| Sebastian Redl | d078e64 | 2010-08-27 23:12:46 +0000 | [diff] [blame] | 6471 |                                    SourceLocation InlineLoc, | 
| Abramo Bagnara | acba90f | 2011-03-08 12:38:20 +0000 | [diff] [blame] | 6472 |                                    SourceLocation NamespaceLoc, | 
| John McCall | ea31864 | 2010-08-26 09:15:37 +0000 | [diff] [blame] | 6473 |                                    SourceLocation IdentLoc, | 
 | 6474 |                                    IdentifierInfo *II, | 
 | 6475 |                                    SourceLocation LBrace, | 
 | 6476 |                                    AttributeList *AttrList) { | 
| Abramo Bagnara | acba90f | 2011-03-08 12:38:20 +0000 | [diff] [blame] | 6477 |   SourceLocation StartLoc = InlineLoc.isValid() ? InlineLoc : NamespaceLoc; | 
 | 6478 |   // For anonymous namespace, take the location of the left brace. | 
 | 6479 |   SourceLocation Loc = II ? IdentLoc : LBrace; | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6480 |   bool IsInline = InlineLoc.isValid(); | 
| Douglas Gregor | 6731074 | 2012-01-10 22:14:10 +0000 | [diff] [blame] | 6481 |   bool IsInvalid = false; | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6482 |   bool IsStd = false; | 
 | 6483 |   bool AddToKnown = false; | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6484 |   Scope *DeclRegionScope = NamespcScope->getParent(); | 
 | 6485 |  | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6486 |   NamespaceDecl *PrevNS = 0; | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6487 |   if (II) { | 
 | 6488 |     // C++ [namespace.def]p2: | 
| Douglas Gregor | fe7574b | 2010-10-22 15:24:46 +0000 | [diff] [blame] | 6489 |     //   The identifier in an original-namespace-definition shall not | 
 | 6490 |     //   have been previously defined in the declarative region in | 
 | 6491 |     //   which the original-namespace-definition appears. The | 
 | 6492 |     //   identifier in an original-namespace-definition is the name of | 
 | 6493 |     //   the namespace. Subsequently in that declarative region, it is | 
 | 6494 |     //   treated as an original-namespace-name. | 
 | 6495 |     // | 
 | 6496 |     // Since namespace names are unique in their scope, and we don't | 
| Douglas Gregor | 010157f | 2011-05-06 23:28:47 +0000 | [diff] [blame] | 6497 |     // look through using directives, just look for any ordinary names. | 
 | 6498 |      | 
 | 6499 |     const unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Member |  | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6500 |     Decl::IDNS_Type | Decl::IDNS_Using | Decl::IDNS_Tag |  | 
 | 6501 |     Decl::IDNS_Namespace; | 
| Douglas Gregor | 010157f | 2011-05-06 23:28:47 +0000 | [diff] [blame] | 6502 |     NamedDecl *PrevDecl = 0; | 
| David Blaikie | 3bc93e3 | 2012-12-19 00:45:41 +0000 | [diff] [blame] | 6503 |     DeclContext::lookup_result R = CurContext->getRedeclContext()->lookup(II); | 
 | 6504 |     for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; | 
 | 6505 |          ++I) { | 
 | 6506 |       if ((*I)->getIdentifierNamespace() & IDNS) { | 
 | 6507 |         PrevDecl = *I; | 
| Douglas Gregor | 010157f | 2011-05-06 23:28:47 +0000 | [diff] [blame] | 6508 |         break; | 
 | 6509 |       } | 
 | 6510 |     } | 
 | 6511 |      | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6512 |     PrevNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl); | 
 | 6513 |      | 
 | 6514 |     if (PrevNS) { | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 6515 |       // This is an extended namespace definition. | 
| Richard Smith | d1a55a6 | 2012-10-04 22:13:39 +0000 | [diff] [blame] | 6516 |       if (IsInline != PrevNS->isInline()) | 
 | 6517 |         DiagnoseNamespaceInlineMismatch(*this, NamespaceLoc, Loc, II, | 
 | 6518 |                                         &IsInline, PrevNS); | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 6519 |     } else if (PrevDecl) { | 
 | 6520 |       // This is an invalid name redefinition. | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6521 |       Diag(Loc, diag::err_redefinition_different_kind) | 
 | 6522 |         << II; | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 6523 |       Diag(PrevDecl->getLocation(), diag::note_previous_definition); | 
| Douglas Gregor | 6731074 | 2012-01-10 22:14:10 +0000 | [diff] [blame] | 6524 |       IsInvalid = true; | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 6525 |       // Continue on to push Namespc as current DeclContext and return it. | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6526 |     } else if (II->isStr("std") && | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 6527 |                CurContext->getRedeclContext()->isTranslationUnit()) { | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 6528 |       // This is the first "real" definition of the namespace "std", so update | 
 | 6529 |       // our cache of the "std" namespace to point at this definition. | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6530 |       PrevNS = getStdNamespace(); | 
 | 6531 |       IsStd = true; | 
 | 6532 |       AddToKnown = !IsInline; | 
 | 6533 |     } else { | 
 | 6534 |       // We've seen this namespace for the first time. | 
 | 6535 |       AddToKnown = !IsInline; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6536 |     } | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 6537 |   } else { | 
| John McCall | 9aeed32 | 2009-10-01 00:25:31 +0000 | [diff] [blame] | 6538 |     // Anonymous namespaces. | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6539 |      | 
 | 6540 |     // Determine whether the parent already has an anonymous namespace. | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 6541 |     DeclContext *Parent = CurContext->getRedeclContext(); | 
| John McCall | 5fdd764 | 2009-12-16 02:06:49 +0000 | [diff] [blame] | 6542 |     if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(Parent)) { | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6543 |       PrevNS = TU->getAnonymousNamespace(); | 
| John McCall | 5fdd764 | 2009-12-16 02:06:49 +0000 | [diff] [blame] | 6544 |     } else { | 
 | 6545 |       NamespaceDecl *ND = cast<NamespaceDecl>(Parent); | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6546 |       PrevNS = ND->getAnonymousNamespace(); | 
| John McCall | 5fdd764 | 2009-12-16 02:06:49 +0000 | [diff] [blame] | 6547 |     } | 
 | 6548 |  | 
| Richard Smith | d1a55a6 | 2012-10-04 22:13:39 +0000 | [diff] [blame] | 6549 |     if (PrevNS && IsInline != PrevNS->isInline()) | 
 | 6550 |       DiagnoseNamespaceInlineMismatch(*this, NamespaceLoc, NamespaceLoc, II, | 
 | 6551 |                                       &IsInline, PrevNS); | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6552 |   } | 
 | 6553 |    | 
 | 6554 |   NamespaceDecl *Namespc = NamespaceDecl::Create(Context, CurContext, IsInline, | 
 | 6555 |                                                  StartLoc, Loc, II, PrevNS); | 
| Douglas Gregor | 6731074 | 2012-01-10 22:14:10 +0000 | [diff] [blame] | 6556 |   if (IsInvalid) | 
 | 6557 |     Namespc->setInvalidDecl(); | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6558 |    | 
 | 6559 |   ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList); | 
| Sebastian Redl | 4e4d570 | 2010-08-31 00:36:36 +0000 | [diff] [blame] | 6560 |  | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6561 |   // FIXME: Should we be merging attributes? | 
 | 6562 |   if (const VisibilityAttr *Attr = Namespc->getAttr<VisibilityAttr>()) | 
| Rafael Espindola | 20039ae | 2012-02-01 23:24:59 +0000 | [diff] [blame] | 6563 |     PushNamespaceVisibilityAttr(Attr, Loc); | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6564 |  | 
 | 6565 |   if (IsStd) | 
 | 6566 |     StdNamespace = Namespc; | 
 | 6567 |   if (AddToKnown) | 
 | 6568 |     KnownNamespaces[Namespc] = false; | 
 | 6569 |    | 
 | 6570 |   if (II) { | 
 | 6571 |     PushOnScopeChains(Namespc, DeclRegionScope); | 
 | 6572 |   } else { | 
 | 6573 |     // Link the anonymous namespace into its parent. | 
 | 6574 |     DeclContext *Parent = CurContext->getRedeclContext(); | 
 | 6575 |     if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(Parent)) { | 
 | 6576 |       TU->setAnonymousNamespace(Namespc); | 
 | 6577 |     } else { | 
 | 6578 |       cast<NamespaceDecl>(Parent)->setAnonymousNamespace(Namespc); | 
| John McCall | 5fdd764 | 2009-12-16 02:06:49 +0000 | [diff] [blame] | 6579 |     } | 
| John McCall | 9aeed32 | 2009-10-01 00:25:31 +0000 | [diff] [blame] | 6580 |  | 
| Douglas Gregor | a418147 | 2010-03-24 00:46:35 +0000 | [diff] [blame] | 6581 |     CurContext->addDecl(Namespc); | 
 | 6582 |  | 
| John McCall | 9aeed32 | 2009-10-01 00:25:31 +0000 | [diff] [blame] | 6583 |     // C++ [namespace.unnamed]p1.  An unnamed-namespace-definition | 
 | 6584 |     //   behaves as if it were replaced by | 
 | 6585 |     //     namespace unique { /* empty body */ } | 
 | 6586 |     //     using namespace unique; | 
 | 6587 |     //     namespace unique { namespace-body } | 
 | 6588 |     //   where all occurrences of 'unique' in a translation unit are | 
 | 6589 |     //   replaced by the same identifier and this identifier differs | 
 | 6590 |     //   from all other identifiers in the entire program. | 
 | 6591 |  | 
 | 6592 |     // We just create the namespace with an empty name and then add an | 
 | 6593 |     // implicit using declaration, just like the standard suggests. | 
 | 6594 |     // | 
 | 6595 |     // CodeGen enforces the "universally unique" aspect by giving all | 
 | 6596 |     // declarations semantically contained within an anonymous | 
 | 6597 |     // namespace internal linkage. | 
 | 6598 |  | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6599 |     if (!PrevNS) { | 
| John McCall | 5fdd764 | 2009-12-16 02:06:49 +0000 | [diff] [blame] | 6600 |       UsingDirectiveDecl* UD | 
| Nick Lewycky | 4b7631b | 2012-11-04 20:21:54 +0000 | [diff] [blame] | 6601 |         = UsingDirectiveDecl::Create(Context, Parent, | 
| John McCall | 5fdd764 | 2009-12-16 02:06:49 +0000 | [diff] [blame] | 6602 |                                      /* 'using' */ LBrace, | 
 | 6603 |                                      /* 'namespace' */ SourceLocation(), | 
| Douglas Gregor | db99241 | 2011-02-25 16:33:46 +0000 | [diff] [blame] | 6604 |                                      /* qualifier */ NestedNameSpecifierLoc(), | 
| John McCall | 5fdd764 | 2009-12-16 02:06:49 +0000 | [diff] [blame] | 6605 |                                      /* identifier */ SourceLocation(), | 
 | 6606 |                                      Namespc, | 
| Nick Lewycky | 4b7631b | 2012-11-04 20:21:54 +0000 | [diff] [blame] | 6607 |                                      /* Ancestor */ Parent); | 
| John McCall | 5fdd764 | 2009-12-16 02:06:49 +0000 | [diff] [blame] | 6608 |       UD->setImplicit(); | 
| Nick Lewycky | 4b7631b | 2012-11-04 20:21:54 +0000 | [diff] [blame] | 6609 |       Parent->addDecl(UD); | 
| John McCall | 5fdd764 | 2009-12-16 02:06:49 +0000 | [diff] [blame] | 6610 |     } | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6611 |   } | 
 | 6612 |  | 
| Dmitri Gribenko | a5ef44f | 2012-07-11 21:38:39 +0000 | [diff] [blame] | 6613 |   ActOnDocumentableDecl(Namespc); | 
 | 6614 |  | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6615 |   // Although we could have an invalid decl (i.e. the namespace name is a | 
 | 6616 |   // redefinition), push it as current DeclContext and try to continue parsing. | 
| Mike Stump | 390b4cc | 2009-05-16 07:39:55 +0000 | [diff] [blame] | 6617 |   // FIXME: We should be able to push Namespc here, so that the each DeclContext | 
 | 6618 |   // for the namespace has the declarations that showed up in that particular | 
 | 6619 |   // namespace definition. | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 6620 |   PushDeclContext(NamespcScope, Namespc); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6621 |   return Namespc; | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6622 | } | 
 | 6623 |  | 
| Sebastian Redl | eb0d8c9 | 2009-11-23 15:34:23 +0000 | [diff] [blame] | 6624 | /// getNamespaceDecl - Returns the namespace a decl represents. If the decl | 
 | 6625 | /// is a namespace alias, returns the namespace it points to. | 
 | 6626 | static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) { | 
 | 6627 |   if (NamespaceAliasDecl *AD = dyn_cast_or_null<NamespaceAliasDecl>(D)) | 
 | 6628 |     return AD->getNamespace(); | 
 | 6629 |   return dyn_cast_or_null<NamespaceDecl>(D); | 
 | 6630 | } | 
 | 6631 |  | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6632 | /// ActOnFinishNamespaceDef - This callback is called after a namespace is | 
 | 6633 | /// exited. Decl is the DeclTy returned by ActOnStartNamespaceDef. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6634 | void Sema::ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace) { | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6635 |   NamespaceDecl *Namespc = dyn_cast_or_null<NamespaceDecl>(Dcl); | 
 | 6636 |   assert(Namespc && "Invalid parameter, expected NamespaceDecl"); | 
| Abramo Bagnara | acba90f | 2011-03-08 12:38:20 +0000 | [diff] [blame] | 6637 |   Namespc->setRBraceLoc(RBrace); | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6638 |   PopDeclContext(); | 
| Eli Friedman | aa8b0d1 | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 6639 |   if (Namespc->hasAttr<VisibilityAttr>()) | 
| Rafael Espindola | 20039ae | 2012-02-01 23:24:59 +0000 | [diff] [blame] | 6640 |     PopPragmaVisibility(true, RBrace); | 
| Argyrios Kyrtzidis | 2d1c5d3 | 2008-04-27 13:50:30 +0000 | [diff] [blame] | 6641 | } | 
| Argyrios Kyrtzidis | 73a0d88 | 2008-10-06 17:10:33 +0000 | [diff] [blame] | 6642 |  | 
| John McCall | 384aff8 | 2010-08-25 07:42:41 +0000 | [diff] [blame] | 6643 | CXXRecordDecl *Sema::getStdBadAlloc() const { | 
 | 6644 |   return cast_or_null<CXXRecordDecl>( | 
 | 6645 |                                   StdBadAlloc.get(Context.getExternalSource())); | 
 | 6646 | } | 
 | 6647 |  | 
 | 6648 | NamespaceDecl *Sema::getStdNamespace() const { | 
 | 6649 |   return cast_or_null<NamespaceDecl>( | 
 | 6650 |                                  StdNamespace.get(Context.getExternalSource())); | 
 | 6651 | } | 
 | 6652 |  | 
| Douglas Gregor | 6699220 | 2010-06-29 17:53:46 +0000 | [diff] [blame] | 6653 | /// \brief Retrieve the special "std" namespace, which may require us to  | 
 | 6654 | /// implicitly define the namespace. | 
| Argyrios Kyrtzidis | 26faaac | 2010-08-02 07:14:39 +0000 | [diff] [blame] | 6655 | NamespaceDecl *Sema::getOrCreateStdNamespace() { | 
| Douglas Gregor | 6699220 | 2010-06-29 17:53:46 +0000 | [diff] [blame] | 6656 |   if (!StdNamespace) { | 
 | 6657 |     // The "std" namespace has not yet been defined, so build one implicitly. | 
 | 6658 |     StdNamespace = NamespaceDecl::Create(Context,  | 
 | 6659 |                                          Context.getTranslationUnitDecl(), | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6660 |                                          /*Inline=*/false, | 
| Abramo Bagnara | acba90f | 2011-03-08 12:38:20 +0000 | [diff] [blame] | 6661 |                                          SourceLocation(), SourceLocation(), | 
| Douglas Gregor | f5c9f9f | 2012-01-07 09:11:48 +0000 | [diff] [blame] | 6662 |                                          &PP.getIdentifierTable().get("std"), | 
 | 6663 |                                          /*PrevDecl=*/0); | 
| Argyrios Kyrtzidis | 76c38d3 | 2010-08-02 07:14:54 +0000 | [diff] [blame] | 6664 |     getStdNamespace()->setImplicit(true); | 
| Douglas Gregor | 6699220 | 2010-06-29 17:53:46 +0000 | [diff] [blame] | 6665 |   } | 
 | 6666 |    | 
| Argyrios Kyrtzidis | 76c38d3 | 2010-08-02 07:14:54 +0000 | [diff] [blame] | 6667 |   return getStdNamespace(); | 
| Douglas Gregor | 6699220 | 2010-06-29 17:53:46 +0000 | [diff] [blame] | 6668 | } | 
 | 6669 |  | 
| Sebastian Redl | 395e04d | 2012-01-17 22:49:33 +0000 | [diff] [blame] | 6670 | bool Sema::isStdInitializerList(QualType Ty, QualType *Element) { | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 6671 |   assert(getLangOpts().CPlusPlus && | 
| Sebastian Redl | 395e04d | 2012-01-17 22:49:33 +0000 | [diff] [blame] | 6672 |          "Looking for std::initializer_list outside of C++."); | 
 | 6673 |  | 
 | 6674 |   // We're looking for implicit instantiations of | 
 | 6675 |   // template <typename E> class std::initializer_list. | 
 | 6676 |  | 
 | 6677 |   if (!StdNamespace) // If we haven't seen namespace std yet, this can't be it. | 
 | 6678 |     return false; | 
 | 6679 |  | 
| Sebastian Redl | 84760e3 | 2012-01-17 22:49:58 +0000 | [diff] [blame] | 6680 |   ClassTemplateDecl *Template = 0; | 
 | 6681 |   const TemplateArgument *Arguments = 0; | 
| Sebastian Redl | 395e04d | 2012-01-17 22:49:33 +0000 | [diff] [blame] | 6682 |  | 
| Sebastian Redl | 84760e3 | 2012-01-17 22:49:58 +0000 | [diff] [blame] | 6683 |   if (const RecordType *RT = Ty->getAs<RecordType>()) { | 
| Sebastian Redl | 395e04d | 2012-01-17 22:49:33 +0000 | [diff] [blame] | 6684 |  | 
| Sebastian Redl | 84760e3 | 2012-01-17 22:49:58 +0000 | [diff] [blame] | 6685 |     ClassTemplateSpecializationDecl *Specialization = | 
 | 6686 |         dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); | 
 | 6687 |     if (!Specialization) | 
 | 6688 |       return false; | 
| Sebastian Redl | 395e04d | 2012-01-17 22:49:33 +0000 | [diff] [blame] | 6689 |  | 
| Sebastian Redl | 84760e3 | 2012-01-17 22:49:58 +0000 | [diff] [blame] | 6690 |     Template = Specialization->getSpecializedTemplate(); | 
 | 6691 |     Arguments = Specialization->getTemplateArgs().data(); | 
 | 6692 |   } else if (const TemplateSpecializationType *TST = | 
 | 6693 |                  Ty->getAs<TemplateSpecializationType>()) { | 
 | 6694 |     Template = dyn_cast_or_null<ClassTemplateDecl>( | 
 | 6695 |         TST->getTemplateName().getAsTemplateDecl()); | 
 | 6696 |     Arguments = TST->getArgs(); | 
 | 6697 |   } | 
 | 6698 |   if (!Template) | 
 | 6699 |     return false; | 
| Sebastian Redl | 395e04d | 2012-01-17 22:49:33 +0000 | [diff] [blame] | 6700 |  | 
 | 6701 |   if (!StdInitializerList) { | 
 | 6702 |     // Haven't recognized std::initializer_list yet, maybe this is it. | 
 | 6703 |     CXXRecordDecl *TemplateClass = Template->getTemplatedDecl(); | 
 | 6704 |     if (TemplateClass->getIdentifier() != | 
 | 6705 |             &PP.getIdentifierTable().get("initializer_list") || | 
| Sebastian Redl | b832f6d | 2012-01-23 22:09:39 +0000 | [diff] [blame] | 6706 |         !getStdNamespace()->InEnclosingNamespaceSetOf( | 
 | 6707 |             TemplateClass->getDeclContext())) | 
| Sebastian Redl | 395e04d | 2012-01-17 22:49:33 +0000 | [diff] [blame] | 6708 |       return false; | 
 | 6709 |     // This is a template called std::initializer_list, but is it the right | 
 | 6710 |     // template? | 
 | 6711 |     TemplateParameterList *Params = Template->getTemplateParameters(); | 
| Sebastian Redl | b832f6d | 2012-01-23 22:09:39 +0000 | [diff] [blame] | 6712 |     if (Params->getMinRequiredArguments() != 1) | 
| Sebastian Redl | 395e04d | 2012-01-17 22:49:33 +0000 | [diff] [blame] | 6713 |       return false; | 
 | 6714 |     if (!isa<TemplateTypeParmDecl>(Params->getParam(0))) | 
 | 6715 |       return false; | 
 | 6716 |  | 
 | 6717 |     // It's the right template. | 
 | 6718 |     StdInitializerList = Template; | 
 | 6719 |   } | 
 | 6720 |  | 
 | 6721 |   if (Template != StdInitializerList) | 
 | 6722 |     return false; | 
 | 6723 |  | 
 | 6724 |   // This is an instance of std::initializer_list. Find the argument type. | 
| Sebastian Redl | 84760e3 | 2012-01-17 22:49:58 +0000 | [diff] [blame] | 6725 |   if (Element) | 
 | 6726 |     *Element = Arguments[0].getAsType(); | 
| Sebastian Redl | 395e04d | 2012-01-17 22:49:33 +0000 | [diff] [blame] | 6727 |   return true; | 
 | 6728 | } | 
 | 6729 |  | 
| Sebastian Redl | 62b7cfb | 2012-01-17 22:50:08 +0000 | [diff] [blame] | 6730 | static ClassTemplateDecl *LookupStdInitializerList(Sema &S, SourceLocation Loc){ | 
 | 6731 |   NamespaceDecl *Std = S.getStdNamespace(); | 
 | 6732 |   if (!Std) { | 
 | 6733 |     S.Diag(Loc, diag::err_implied_std_initializer_list_not_found); | 
 | 6734 |     return 0; | 
 | 6735 |   } | 
 | 6736 |  | 
 | 6737 |   LookupResult Result(S, &S.PP.getIdentifierTable().get("initializer_list"), | 
 | 6738 |                       Loc, Sema::LookupOrdinaryName); | 
 | 6739 |   if (!S.LookupQualifiedName(Result, Std)) { | 
 | 6740 |     S.Diag(Loc, diag::err_implied_std_initializer_list_not_found); | 
 | 6741 |     return 0; | 
 | 6742 |   } | 
 | 6743 |   ClassTemplateDecl *Template = Result.getAsSingle<ClassTemplateDecl>(); | 
 | 6744 |   if (!Template) { | 
 | 6745 |     Result.suppressDiagnostics(); | 
 | 6746 |     // We found something weird. Complain about the first thing we found. | 
 | 6747 |     NamedDecl *Found = *Result.begin(); | 
 | 6748 |     S.Diag(Found->getLocation(), diag::err_malformed_std_initializer_list); | 
 | 6749 |     return 0; | 
 | 6750 |   } | 
 | 6751 |  | 
 | 6752 |   // We found some template called std::initializer_list. Now verify that it's | 
 | 6753 |   // correct. | 
 | 6754 |   TemplateParameterList *Params = Template->getTemplateParameters(); | 
| Sebastian Redl | b832f6d | 2012-01-23 22:09:39 +0000 | [diff] [blame] | 6755 |   if (Params->getMinRequiredArguments() != 1 || | 
 | 6756 |       !isa<TemplateTypeParmDecl>(Params->getParam(0))) { | 
| Sebastian Redl | 62b7cfb | 2012-01-17 22:50:08 +0000 | [diff] [blame] | 6757 |     S.Diag(Template->getLocation(), diag::err_malformed_std_initializer_list); | 
 | 6758 |     return 0; | 
 | 6759 |   } | 
 | 6760 |  | 
 | 6761 |   return Template; | 
 | 6762 | } | 
 | 6763 |  | 
 | 6764 | QualType Sema::BuildStdInitializerList(QualType Element, SourceLocation Loc) { | 
 | 6765 |   if (!StdInitializerList) { | 
 | 6766 |     StdInitializerList = LookupStdInitializerList(*this, Loc); | 
 | 6767 |     if (!StdInitializerList) | 
 | 6768 |       return QualType(); | 
 | 6769 |   } | 
 | 6770 |  | 
 | 6771 |   TemplateArgumentListInfo Args(Loc, Loc); | 
 | 6772 |   Args.addArgument(TemplateArgumentLoc(TemplateArgument(Element), | 
 | 6773 |                                        Context.getTrivialTypeSourceInfo(Element, | 
 | 6774 |                                                                         Loc))); | 
 | 6775 |   return Context.getCanonicalType( | 
 | 6776 |       CheckTemplateIdType(TemplateName(StdInitializerList), Loc, Args)); | 
 | 6777 | } | 
 | 6778 |  | 
| Sebastian Redl | 98d3606 | 2012-01-17 22:50:14 +0000 | [diff] [blame] | 6779 | bool Sema::isInitListConstructor(const CXXConstructorDecl* Ctor) { | 
 | 6780 |   // C++ [dcl.init.list]p2: | 
 | 6781 |   //   A constructor is an initializer-list constructor if its first parameter | 
 | 6782 |   //   is of type std::initializer_list<E> or reference to possibly cv-qualified | 
 | 6783 |   //   std::initializer_list<E> for some type E, and either there are no other | 
 | 6784 |   //   parameters or else all other parameters have default arguments. | 
 | 6785 |   if (Ctor->getNumParams() < 1 || | 
 | 6786 |       (Ctor->getNumParams() > 1 && !Ctor->getParamDecl(1)->hasDefaultArg())) | 
 | 6787 |     return false; | 
 | 6788 |  | 
 | 6789 |   QualType ArgType = Ctor->getParamDecl(0)->getType(); | 
 | 6790 |   if (const ReferenceType *RT = ArgType->getAs<ReferenceType>()) | 
 | 6791 |     ArgType = RT->getPointeeType().getUnqualifiedType(); | 
 | 6792 |  | 
 | 6793 |   return isStdInitializerList(ArgType, 0); | 
 | 6794 | } | 
 | 6795 |  | 
| Douglas Gregor | 9172aa6 | 2011-03-26 22:25:30 +0000 | [diff] [blame] | 6796 | /// \brief Determine whether a using statement is in a context where it will be | 
 | 6797 | /// apply in all contexts. | 
 | 6798 | static bool IsUsingDirectiveInToplevelContext(DeclContext *CurContext) { | 
 | 6799 |   switch (CurContext->getDeclKind()) { | 
 | 6800 |     case Decl::TranslationUnit: | 
 | 6801 |       return true; | 
 | 6802 |     case Decl::LinkageSpec: | 
 | 6803 |       return IsUsingDirectiveInToplevelContext(CurContext->getParent()); | 
 | 6804 |     default: | 
 | 6805 |       return false; | 
 | 6806 |   } | 
 | 6807 | } | 
 | 6808 |  | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 6809 | namespace { | 
 | 6810 |  | 
 | 6811 | // Callback to only accept typo corrections that are namespaces. | 
 | 6812 | class NamespaceValidatorCCC : public CorrectionCandidateCallback { | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 6813 | public: | 
 | 6814 |   bool ValidateCandidate(const TypoCorrection &candidate) LLVM_OVERRIDE { | 
 | 6815 |     if (NamedDecl *ND = candidate.getCorrectionDecl()) | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 6816 |       return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND); | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 6817 |     return false; | 
 | 6818 |   } | 
 | 6819 | }; | 
 | 6820 |  | 
 | 6821 | } | 
 | 6822 |  | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 6823 | static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc, | 
 | 6824 |                                        CXXScopeSpec &SS, | 
 | 6825 |                                        SourceLocation IdentLoc, | 
 | 6826 |                                        IdentifierInfo *Ident) { | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 6827 |   NamespaceValidatorCCC Validator; | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 6828 |   R.clear(); | 
 | 6829 |   if (TypoCorrection Corrected = S.CorrectTypo(R.getLookupNameInfo(), | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 6830 |                                                R.getLookupKind(), Sc, &SS, | 
| Kaelyn Uhrain | 16e46dd | 2012-01-31 23:49:25 +0000 | [diff] [blame] | 6831 |                                                Validator)) { | 
| Kaelyn Uhrain | b2567dd | 2013-07-02 23:47:44 +0000 | [diff] [blame] | 6832 |     if (DeclContext *DC = S.computeDeclContext(SS, false)) { | 
| Richard Smith | 2d67097 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 6833 |       std::string CorrectedStr(Corrected.getAsString(S.getLangOpts())); | 
 | 6834 |       bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && | 
| Kaelyn Uhrain | b2567dd | 2013-07-02 23:47:44 +0000 | [diff] [blame] | 6835 |                               Ident->getName().equals(CorrectedStr); | 
| Richard Smith | 2d67097 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 6836 |       S.diagnoseTypo(Corrected, | 
 | 6837 |                      S.PDiag(diag::err_using_directive_member_suggest) | 
 | 6838 |                        << Ident << DC << DroppedSpecifier << SS.getRange(), | 
 | 6839 |                      S.PDiag(diag::note_namespace_defined_here)); | 
| Kaelyn Uhrain | b2567dd | 2013-07-02 23:47:44 +0000 | [diff] [blame] | 6840 |     } else { | 
| Richard Smith | 2d67097 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 6841 |       S.diagnoseTypo(Corrected, | 
 | 6842 |                      S.PDiag(diag::err_using_directive_suggest) << Ident, | 
 | 6843 |                      S.PDiag(diag::note_namespace_defined_here)); | 
| Kaelyn Uhrain | b2567dd | 2013-07-02 23:47:44 +0000 | [diff] [blame] | 6844 |     } | 
| Kaelyn Uhrain | 7d5e694 | 2012-01-11 19:37:46 +0000 | [diff] [blame] | 6845 |     R.addDecl(Corrected.getCorrectionDecl()); | 
 | 6846 |     return true; | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 6847 |   } | 
 | 6848 |   return false; | 
 | 6849 | } | 
 | 6850 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6851 | Decl *Sema::ActOnUsingDirective(Scope *S, | 
| Chris Lattner | b28317a | 2009-03-28 19:18:32 +0000 | [diff] [blame] | 6852 |                                           SourceLocation UsingLoc, | 
 | 6853 |                                           SourceLocation NamespcLoc, | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 6854 |                                           CXXScopeSpec &SS, | 
| Chris Lattner | b28317a | 2009-03-28 19:18:32 +0000 | [diff] [blame] | 6855 |                                           SourceLocation IdentLoc, | 
 | 6856 |                                           IdentifierInfo *NamespcName, | 
 | 6857 |                                           AttributeList *AttrList) { | 
| Douglas Gregor | f780abc | 2008-12-30 03:27:21 +0000 | [diff] [blame] | 6858 |   assert(!SS.isInvalid() && "Invalid CXXScopeSpec."); | 
 | 6859 |   assert(NamespcName && "Invalid NamespcName."); | 
 | 6860 |   assert(IdentLoc.isValid() && "Invalid NamespceName location."); | 
| John McCall | 78b8105 | 2010-11-10 02:40:36 +0000 | [diff] [blame] | 6861 |  | 
 | 6862 |   // This can only happen along a recovery path. | 
 | 6863 |   while (S->getFlags() & Scope::TemplateParamScope) | 
 | 6864 |     S = S->getParent(); | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 6865 |   assert(S->getFlags() & Scope::DeclScope && "Invalid Scope."); | 
| Douglas Gregor | f780abc | 2008-12-30 03:27:21 +0000 | [diff] [blame] | 6866 |  | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 6867 |   UsingDirectiveDecl *UDir = 0; | 
| Douglas Gregor | 6699220 | 2010-06-29 17:53:46 +0000 | [diff] [blame] | 6868 |   NestedNameSpecifier *Qualifier = 0; | 
 | 6869 |   if (SS.isSet()) | 
 | 6870 |     Qualifier = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); | 
 | 6871 |    | 
| Douglas Gregor | eb11cd0 | 2009-01-14 22:20:51 +0000 | [diff] [blame] | 6872 |   // Lookup namespace name. | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 6873 |   LookupResult R(*this, NamespcName, IdentLoc, LookupNamespaceName); | 
 | 6874 |   LookupParsedName(R, S, &SS); | 
 | 6875 |   if (R.isAmbiguous()) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6876 |     return 0; | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 6877 |  | 
| Douglas Gregor | 6699220 | 2010-06-29 17:53:46 +0000 | [diff] [blame] | 6878 |   if (R.empty()) { | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 6879 |     R.clear(); | 
| Douglas Gregor | 6699220 | 2010-06-29 17:53:46 +0000 | [diff] [blame] | 6880 |     // Allow "using namespace std;" or "using namespace ::std;" even if  | 
 | 6881 |     // "std" hasn't been defined yet, for GCC compatibility. | 
 | 6882 |     if ((!Qualifier || Qualifier->getKind() == NestedNameSpecifier::Global) && | 
 | 6883 |         NamespcName->isStr("std")) { | 
 | 6884 |       Diag(IdentLoc, diag::ext_using_undefined_std); | 
| Argyrios Kyrtzidis | 26faaac | 2010-08-02 07:14:39 +0000 | [diff] [blame] | 6885 |       R.addDecl(getOrCreateStdNamespace()); | 
| Douglas Gregor | 6699220 | 2010-06-29 17:53:46 +0000 | [diff] [blame] | 6886 |       R.resolveKind(); | 
 | 6887 |     }  | 
 | 6888 |     // Otherwise, attempt typo correction. | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 6889 |     else TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, NamespcName); | 
| Douglas Gregor | 6699220 | 2010-06-29 17:53:46 +0000 | [diff] [blame] | 6890 |   } | 
 | 6891 |    | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 6892 |   if (!R.empty()) { | 
| Sebastian Redl | eb0d8c9 | 2009-11-23 15:34:23 +0000 | [diff] [blame] | 6893 |     NamedDecl *Named = R.getFoundDecl(); | 
 | 6894 |     assert((isa<NamespaceDecl>(Named) || isa<NamespaceAliasDecl>(Named)) | 
 | 6895 |         && "expected namespace decl"); | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 6896 |     // C++ [namespace.udir]p1: | 
 | 6897 |     //   A using-directive specifies that the names in the nominated | 
 | 6898 |     //   namespace can be used in the scope in which the | 
 | 6899 |     //   using-directive appears after the using-directive. During | 
 | 6900 |     //   unqualified name lookup (3.4.1), the names appear as if they | 
 | 6901 |     //   were declared in the nearest enclosing namespace which | 
 | 6902 |     //   contains both the using-directive and the nominated | 
| Eli Friedman | 33a3138 | 2009-08-05 19:21:58 +0000 | [diff] [blame] | 6903 |     //   namespace. [Note: in this context, "contains" means "contains | 
 | 6904 |     //   directly or indirectly". ] | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 6905 |  | 
 | 6906 |     // Find enclosing context containing both using-directive and | 
 | 6907 |     // nominated namespace. | 
| Sebastian Redl | eb0d8c9 | 2009-11-23 15:34:23 +0000 | [diff] [blame] | 6908 |     NamespaceDecl *NS = getNamespaceDecl(Named); | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 6909 |     DeclContext *CommonAncestor = cast<DeclContext>(NS); | 
 | 6910 |     while (CommonAncestor && !CommonAncestor->Encloses(CurContext)) | 
 | 6911 |       CommonAncestor = CommonAncestor->getParent(); | 
 | 6912 |  | 
| Sebastian Redl | eb0d8c9 | 2009-11-23 15:34:23 +0000 | [diff] [blame] | 6913 |     UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc, NamespcLoc, | 
| Douglas Gregor | db99241 | 2011-02-25 16:33:46 +0000 | [diff] [blame] | 6914 |                                       SS.getWithLocInContext(Context), | 
| Sebastian Redl | eb0d8c9 | 2009-11-23 15:34:23 +0000 | [diff] [blame] | 6915 |                                       IdentLoc, Named, CommonAncestor); | 
| Douglas Gregor | d6a49bb | 2011-03-18 16:10:52 +0000 | [diff] [blame] | 6916 |  | 
| Douglas Gregor | 9172aa6 | 2011-03-26 22:25:30 +0000 | [diff] [blame] | 6917 |     if (IsUsingDirectiveInToplevelContext(CurContext) && | 
| Eli Friedman | 2414697 | 2013-08-22 00:27:10 +0000 | [diff] [blame] | 6918 |         !SourceMgr.isInMainFile(SourceMgr.getExpansionLoc(IdentLoc))) { | 
| Douglas Gregor | d6a49bb | 2011-03-18 16:10:52 +0000 | [diff] [blame] | 6919 |       Diag(IdentLoc, diag::warn_using_directive_in_header); | 
 | 6920 |     } | 
 | 6921 |  | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 6922 |     PushUsingDirective(S, UDir); | 
| Douglas Gregor | f780abc | 2008-12-30 03:27:21 +0000 | [diff] [blame] | 6923 |   } else { | 
| Chris Lattner | ead013e | 2009-01-06 07:24:29 +0000 | [diff] [blame] | 6924 |     Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange(); | 
| Douglas Gregor | f780abc | 2008-12-30 03:27:21 +0000 | [diff] [blame] | 6925 |   } | 
 | 6926 |  | 
| Richard Smith | 6b3d3e5 | 2013-02-20 19:22:51 +0000 | [diff] [blame] | 6927 |   if (UDir) | 
 | 6928 |     ProcessDeclAttributeList(S, UDir, AttrList); | 
 | 6929 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6930 |   return UDir; | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 6931 | } | 
 | 6932 |  | 
 | 6933 | void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) { | 
| Richard Smith | 1b7f9cb | 2012-03-13 03:12:56 +0000 | [diff] [blame] | 6934 |   // If the scope has an associated entity and the using directive is at | 
 | 6935 |   // namespace or translation unit scope, add the UsingDirectiveDecl into | 
 | 6936 |   // its lookup structure so qualified name lookup can find it. | 
| Ted Kremenek | f0d5861 | 2013-10-08 17:08:03 +0000 | [diff] [blame^] | 6937 |   DeclContext *Ctx = S->getEntity(); | 
| Richard Smith | 1b7f9cb | 2012-03-13 03:12:56 +0000 | [diff] [blame] | 6938 |   if (Ctx && !Ctx->isFunctionOrMethod()) | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 6939 |     Ctx->addDecl(UDir); | 
| Douglas Gregor | 2a3009a | 2009-02-03 19:21:40 +0000 | [diff] [blame] | 6940 |   else | 
| Richard Smith | 1b7f9cb | 2012-03-13 03:12:56 +0000 | [diff] [blame] | 6941 |     // Otherwise, it is at block sope. The using-directives will affect lookup | 
 | 6942 |     // only to the end of the scope. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6943 |     S->PushUsingDirective(UDir); | 
| Douglas Gregor | f780abc | 2008-12-30 03:27:21 +0000 | [diff] [blame] | 6944 | } | 
| Argyrios Kyrtzidis | 73a0d88 | 2008-10-06 17:10:33 +0000 | [diff] [blame] | 6945 |  | 
| Douglas Gregor | 9cfbe48 | 2009-06-20 00:51:54 +0000 | [diff] [blame] | 6946 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6947 | Decl *Sema::ActOnUsingDeclaration(Scope *S, | 
| John McCall | 78b8105 | 2010-11-10 02:40:36 +0000 | [diff] [blame] | 6948 |                                   AccessSpecifier AS, | 
 | 6949 |                                   bool HasUsingKeyword, | 
 | 6950 |                                   SourceLocation UsingLoc, | 
 | 6951 |                                   CXXScopeSpec &SS, | 
 | 6952 |                                   UnqualifiedId &Name, | 
 | 6953 |                                   AttributeList *AttrList, | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 6954 |                                   bool HasTypenameKeyword, | 
| John McCall | 78b8105 | 2010-11-10 02:40:36 +0000 | [diff] [blame] | 6955 |                                   SourceLocation TypenameLoc) { | 
| Douglas Gregor | 9cfbe48 | 2009-06-20 00:51:54 +0000 | [diff] [blame] | 6956 |   assert(S->getFlags() & Scope::DeclScope && "Invalid Scope."); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6957 |  | 
| Douglas Gregor | 12c118a | 2009-11-04 16:30:06 +0000 | [diff] [blame] | 6958 |   switch (Name.getKind()) { | 
| Fariborz Jahanian | 98a5403 | 2011-07-12 17:16:56 +0000 | [diff] [blame] | 6959 |   case UnqualifiedId::IK_ImplicitSelfParam: | 
| Douglas Gregor | 12c118a | 2009-11-04 16:30:06 +0000 | [diff] [blame] | 6960 |   case UnqualifiedId::IK_Identifier: | 
 | 6961 |   case UnqualifiedId::IK_OperatorFunctionId: | 
| Sean Hunt | 0486d74 | 2009-11-28 04:44:28 +0000 | [diff] [blame] | 6962 |   case UnqualifiedId::IK_LiteralOperatorId: | 
| Douglas Gregor | 12c118a | 2009-11-04 16:30:06 +0000 | [diff] [blame] | 6963 |   case UnqualifiedId::IK_ConversionFunctionId: | 
 | 6964 |     break; | 
 | 6965 |        | 
 | 6966 |   case UnqualifiedId::IK_ConstructorName: | 
| Douglas Gregor | 0efc2c1 | 2010-01-13 17:31:36 +0000 | [diff] [blame] | 6967 |   case UnqualifiedId::IK_ConstructorTemplateId: | 
| Richard Smith | a1366cb | 2012-04-27 19:33:05 +0000 | [diff] [blame] | 6968 |     // C++11 inheriting constructors. | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 6969 |     Diag(Name.getLocStart(), | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 6970 |          getLangOpts().CPlusPlus11 ? | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 6971 |            diag::warn_cxx98_compat_using_decl_constructor : | 
| Richard Smith | ebaf0e6 | 2011-10-18 20:49:44 +0000 | [diff] [blame] | 6972 |            diag::err_using_decl_constructor) | 
 | 6973 |       << SS.getRange(); | 
 | 6974 |  | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 6975 |     if (getLangOpts().CPlusPlus11) break; | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 6976 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6977 |     return 0; | 
| Douglas Gregor | 12c118a | 2009-11-04 16:30:06 +0000 | [diff] [blame] | 6978 |        | 
 | 6979 |   case UnqualifiedId::IK_DestructorName: | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 6980 |     Diag(Name.getLocStart(), diag::err_using_decl_destructor) | 
| Douglas Gregor | 12c118a | 2009-11-04 16:30:06 +0000 | [diff] [blame] | 6981 |       << SS.getRange(); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6982 |     return 0; | 
| Douglas Gregor | 12c118a | 2009-11-04 16:30:06 +0000 | [diff] [blame] | 6983 |        | 
 | 6984 |   case UnqualifiedId::IK_TemplateId: | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 6985 |     Diag(Name.getLocStart(), diag::err_using_decl_template_id) | 
| Douglas Gregor | 12c118a | 2009-11-04 16:30:06 +0000 | [diff] [blame] | 6986 |       << SourceRange(Name.TemplateId->LAngleLoc, Name.TemplateId->RAngleLoc); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6987 |     return 0; | 
| Douglas Gregor | 12c118a | 2009-11-04 16:30:06 +0000 | [diff] [blame] | 6988 |   } | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 6989 |  | 
 | 6990 |   DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name); | 
 | 6991 |   DeclarationName TargetName = TargetNameInfo.getName(); | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 6992 |   if (!TargetName) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 6993 |     return 0; | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 6994 |  | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 6995 |   // Warn about access declarations. | 
| John McCall | 60fa3cf | 2009-12-11 02:10:03 +0000 | [diff] [blame] | 6996 |   if (!HasUsingKeyword) { | 
| Enea Zaffanella | d4de59d | 2013-07-17 17:28:56 +0000 | [diff] [blame] | 6997 |     Diag(Name.getLocStart(), | 
| Richard Smith | 1b2209f | 2013-06-13 02:12:17 +0000 | [diff] [blame] | 6998 |          getLangOpts().CPlusPlus11 ? diag::err_access_decl | 
 | 6999 |                                    : diag::warn_access_decl_deprecated) | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 7000 |       << FixItHint::CreateInsertion(SS.getRange().getBegin(), "using "); | 
| John McCall | 60fa3cf | 2009-12-11 02:10:03 +0000 | [diff] [blame] | 7001 |   } | 
 | 7002 |  | 
| Douglas Gregor | 56c0458 | 2010-12-16 00:46:58 +0000 | [diff] [blame] | 7003 |   if (DiagnoseUnexpandedParameterPack(SS, UPPC_UsingDeclaration) || | 
 | 7004 |       DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC_UsingDeclaration)) | 
 | 7005 |     return 0; | 
 | 7006 |  | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7007 |   NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS, | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 7008 |                                         TargetNameInfo, AttrList, | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7009 |                                         /* IsInstantiation */ false, | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7010 |                                         HasTypenameKeyword, TypenameLoc); | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7011 |   if (UD) | 
 | 7012 |     PushOnScopeChains(UD, S, /*AddToContext*/ false); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7013 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 7014 |   return UD; | 
| Anders Carlsson | c72160b | 2009-08-28 05:40:36 +0000 | [diff] [blame] | 7015 | } | 
 | 7016 |  | 
| Douglas Gregor | 09acc98 | 2010-07-07 23:08:52 +0000 | [diff] [blame] | 7017 | /// \brief Determine whether a using declaration considers the given | 
 | 7018 | /// declarations as "equivalent", e.g., if they are redeclarations of | 
 | 7019 | /// the same entity or are both typedefs of the same type. | 
 | 7020 | static bool  | 
 | 7021 | IsEquivalentForUsingDecl(ASTContext &Context, NamedDecl *D1, NamedDecl *D2, | 
 | 7022 |                          bool &SuppressRedeclaration) { | 
 | 7023 |   if (D1->getCanonicalDecl() == D2->getCanonicalDecl()) { | 
 | 7024 |     SuppressRedeclaration = false; | 
 | 7025 |     return true; | 
 | 7026 |   } | 
 | 7027 |  | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7028 |   if (TypedefNameDecl *TD1 = dyn_cast<TypedefNameDecl>(D1)) | 
 | 7029 |     if (TypedefNameDecl *TD2 = dyn_cast<TypedefNameDecl>(D2)) { | 
| Douglas Gregor | 09acc98 | 2010-07-07 23:08:52 +0000 | [diff] [blame] | 7030 |       SuppressRedeclaration = true; | 
 | 7031 |       return Context.hasSameType(TD1->getUnderlyingType(), | 
 | 7032 |                                  TD2->getUnderlyingType()); | 
 | 7033 |     } | 
 | 7034 |  | 
 | 7035 |   return false; | 
 | 7036 | } | 
 | 7037 |  | 
 | 7038 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7039 | /// Determines whether to create a using shadow decl for a particular | 
 | 7040 | /// decl, given the set of decls existing prior to this using lookup. | 
 | 7041 | bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig, | 
 | 7042 |                                 const LookupResult &Previous) { | 
 | 7043 |   // Diagnose finding a decl which is not from a base class of the | 
 | 7044 |   // current class.  We do this now because there are cases where this | 
 | 7045 |   // function will silently decide not to build a shadow decl, which | 
 | 7046 |   // will pre-empt further diagnostics. | 
 | 7047 |   // | 
 | 7048 |   // We don't need to do this in C++0x because we do the check once on | 
 | 7049 |   // the qualifier. | 
 | 7050 |   // | 
 | 7051 |   // FIXME: diagnose the following if we care enough: | 
 | 7052 |   //   struct A { int foo; }; | 
 | 7053 |   //   struct B : A { using A::foo; }; | 
 | 7054 |   //   template <class T> struct C : A {}; | 
 | 7055 |   //   template <class T> struct D : C<T> { using B::foo; } // <--- | 
 | 7056 |   // This is invalid (during instantiation) in C++03 because B::foo | 
 | 7057 |   // resolves to the using decl in B, which is not a base class of D<T>. | 
 | 7058 |   // We can't diagnose it immediately because C<T> is an unknown | 
 | 7059 |   // specialization.  The UsingShadowDecl in D<T> then points directly | 
 | 7060 |   // to A::foo, which will look well-formed when we instantiate. | 
 | 7061 |   // The right solution is to not collapse the shadow-decl chain. | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 7062 |   if (!getLangOpts().CPlusPlus11 && CurContext->isRecord()) { | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7063 |     DeclContext *OrigDC = Orig->getDeclContext(); | 
 | 7064 |  | 
 | 7065 |     // Handle enums and anonymous structs. | 
 | 7066 |     if (isa<EnumDecl>(OrigDC)) OrigDC = OrigDC->getParent(); | 
 | 7067 |     CXXRecordDecl *OrigRec = cast<CXXRecordDecl>(OrigDC); | 
 | 7068 |     while (OrigRec->isAnonymousStructOrUnion()) | 
 | 7069 |       OrigRec = cast<CXXRecordDecl>(OrigRec->getDeclContext()); | 
 | 7070 |  | 
 | 7071 |     if (cast<CXXRecordDecl>(CurContext)->isProvablyNotDerivedFrom(OrigRec)) { | 
 | 7072 |       if (OrigDC == CurContext) { | 
 | 7073 |         Diag(Using->getLocation(), | 
 | 7074 |              diag::err_using_decl_nested_name_specifier_is_current_class) | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7075 |           << Using->getQualifierLoc().getSourceRange(); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7076 |         Diag(Orig->getLocation(), diag::note_using_decl_target); | 
 | 7077 |         return true; | 
 | 7078 |       } | 
 | 7079 |  | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7080 |       Diag(Using->getQualifierLoc().getBeginLoc(), | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7081 |            diag::err_using_decl_nested_name_specifier_is_not_base_class) | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7082 |         << Using->getQualifier() | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7083 |         << cast<CXXRecordDecl>(CurContext) | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7084 |         << Using->getQualifierLoc().getSourceRange(); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7085 |       Diag(Orig->getLocation(), diag::note_using_decl_target); | 
 | 7086 |       return true; | 
 | 7087 |     } | 
 | 7088 |   } | 
 | 7089 |  | 
 | 7090 |   if (Previous.empty()) return false; | 
 | 7091 |  | 
 | 7092 |   NamedDecl *Target = Orig; | 
 | 7093 |   if (isa<UsingShadowDecl>(Target)) | 
 | 7094 |     Target = cast<UsingShadowDecl>(Target)->getTargetDecl(); | 
 | 7095 |  | 
| John McCall | d7533ec | 2009-12-11 02:33:26 +0000 | [diff] [blame] | 7096 |   // If the target happens to be one of the previous declarations, we | 
 | 7097 |   // don't have a conflict. | 
 | 7098 |   //  | 
 | 7099 |   // FIXME: but we might be increasing its access, in which case we | 
 | 7100 |   // should redeclare it. | 
 | 7101 |   NamedDecl *NonTag = 0, *Tag = 0; | 
 | 7102 |   for (LookupResult::iterator I = Previous.begin(), E = Previous.end(); | 
 | 7103 |          I != E; ++I) { | 
 | 7104 |     NamedDecl *D = (*I)->getUnderlyingDecl(); | 
| Douglas Gregor | 09acc98 | 2010-07-07 23:08:52 +0000 | [diff] [blame] | 7105 |     bool Result; | 
 | 7106 |     if (IsEquivalentForUsingDecl(Context, D, Target, Result)) | 
 | 7107 |       return Result; | 
| John McCall | d7533ec | 2009-12-11 02:33:26 +0000 | [diff] [blame] | 7108 |  | 
 | 7109 |     (isa<TagDecl>(D) ? Tag : NonTag) = D; | 
 | 7110 |   } | 
 | 7111 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7112 |   if (Target->isFunctionOrFunctionTemplate()) { | 
 | 7113 |     FunctionDecl *FD; | 
 | 7114 |     if (isa<FunctionTemplateDecl>(Target)) | 
 | 7115 |       FD = cast<FunctionTemplateDecl>(Target)->getTemplatedDecl(); | 
 | 7116 |     else | 
 | 7117 |       FD = cast<FunctionDecl>(Target); | 
 | 7118 |  | 
 | 7119 |     NamedDecl *OldDecl = 0; | 
| John McCall | ad00b77 | 2010-06-16 08:42:20 +0000 | [diff] [blame] | 7120 |     switch (CheckOverload(0, FD, Previous, OldDecl, /*IsForUsingDecl*/ true)) { | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7121 |     case Ovl_Overload: | 
 | 7122 |       return false; | 
 | 7123 |  | 
 | 7124 |     case Ovl_NonFunction: | 
| John McCall | 41ce66f | 2009-12-10 19:51:03 +0000 | [diff] [blame] | 7125 |       Diag(Using->getLocation(), diag::err_using_decl_conflict); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7126 |       break; | 
 | 7127 |        | 
 | 7128 |     // We found a decl with the exact signature. | 
 | 7129 |     case Ovl_Match: | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7130 |       // If we're in a record, we want to hide the target, so we | 
 | 7131 |       // return true (without a diagnostic) to tell the caller not to | 
 | 7132 |       // build a shadow decl. | 
 | 7133 |       if (CurContext->isRecord()) | 
 | 7134 |         return true; | 
 | 7135 |  | 
 | 7136 |       // If we're not in a record, this is an error. | 
| John McCall | 41ce66f | 2009-12-10 19:51:03 +0000 | [diff] [blame] | 7137 |       Diag(Using->getLocation(), diag::err_using_decl_conflict); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7138 |       break; | 
 | 7139 |     } | 
 | 7140 |  | 
 | 7141 |     Diag(Target->getLocation(), diag::note_using_decl_target); | 
 | 7142 |     Diag(OldDecl->getLocation(), diag::note_using_decl_conflict); | 
 | 7143 |     return true; | 
 | 7144 |   } | 
 | 7145 |  | 
 | 7146 |   // Target is not a function. | 
 | 7147 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7148 |   if (isa<TagDecl>(Target)) { | 
 | 7149 |     // No conflict between a tag and a non-tag. | 
 | 7150 |     if (!Tag) return false; | 
 | 7151 |  | 
| John McCall | 41ce66f | 2009-12-10 19:51:03 +0000 | [diff] [blame] | 7152 |     Diag(Using->getLocation(), diag::err_using_decl_conflict); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7153 |     Diag(Target->getLocation(), diag::note_using_decl_target); | 
 | 7154 |     Diag(Tag->getLocation(), diag::note_using_decl_conflict); | 
 | 7155 |     return true; | 
 | 7156 |   } | 
 | 7157 |  | 
 | 7158 |   // No conflict between a tag and a non-tag. | 
 | 7159 |   if (!NonTag) return false; | 
 | 7160 |  | 
| John McCall | 41ce66f | 2009-12-10 19:51:03 +0000 | [diff] [blame] | 7161 |   Diag(Using->getLocation(), diag::err_using_decl_conflict); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7162 |   Diag(Target->getLocation(), diag::note_using_decl_target); | 
 | 7163 |   Diag(NonTag->getLocation(), diag::note_using_decl_conflict); | 
 | 7164 |   return true; | 
 | 7165 | } | 
 | 7166 |  | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7167 | /// Builds a shadow declaration corresponding to a 'using' declaration. | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7168 | UsingShadowDecl *Sema::BuildUsingShadowDecl(Scope *S, | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7169 |                                             UsingDecl *UD, | 
 | 7170 |                                             NamedDecl *Orig) { | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7171 |  | 
 | 7172 |   // If we resolved to another shadow declaration, just coalesce them. | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7173 |   NamedDecl *Target = Orig; | 
 | 7174 |   if (isa<UsingShadowDecl>(Target)) { | 
 | 7175 |     Target = cast<UsingShadowDecl>(Target)->getTargetDecl(); | 
 | 7176 |     assert(!isa<UsingShadowDecl>(Target) && "nested shadow declaration"); | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7177 |   } | 
 | 7178 |    | 
 | 7179 |   UsingShadowDecl *Shadow | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7180 |     = UsingShadowDecl::Create(Context, CurContext, | 
 | 7181 |                               UD->getLocation(), UD, Target); | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7182 |   UD->addShadowDecl(Shadow); | 
| Douglas Gregor | e80622f | 2010-09-29 04:25:11 +0000 | [diff] [blame] | 7183 |    | 
 | 7184 |   Shadow->setAccess(UD->getAccess()); | 
 | 7185 |   if (Orig->isInvalidDecl() || UD->isInvalidDecl()) | 
 | 7186 |     Shadow->setInvalidDecl(); | 
 | 7187 |    | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7188 |   if (S) | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7189 |     PushOnScopeChains(Shadow, S); | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7190 |   else | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7191 |     CurContext->addDecl(Shadow); | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7192 |  | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7193 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7194 |   return Shadow; | 
 | 7195 | } | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7196 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7197 | /// Hides a using shadow declaration.  This is required by the current | 
 | 7198 | /// using-decl implementation when a resolvable using declaration in a | 
 | 7199 | /// class is followed by a declaration which would hide or override | 
 | 7200 | /// one or more of the using decl's targets; for example: | 
 | 7201 | /// | 
 | 7202 | ///   struct Base { void foo(int); }; | 
 | 7203 | ///   struct Derived : Base { | 
 | 7204 | ///     using Base::foo; | 
 | 7205 | ///     void foo(int); | 
 | 7206 | ///   }; | 
 | 7207 | /// | 
 | 7208 | /// The governing language is C++03 [namespace.udecl]p12: | 
 | 7209 | /// | 
 | 7210 | ///   When a using-declaration brings names from a base class into a | 
 | 7211 | ///   derived class scope, member functions in the derived class | 
 | 7212 | ///   override and/or hide member functions with the same name and | 
 | 7213 | ///   parameter types in a base class (rather than conflicting). | 
 | 7214 | /// | 
 | 7215 | /// There are two ways to implement this: | 
 | 7216 | ///   (1) optimistically create shadow decls when they're not hidden | 
 | 7217 | ///       by existing declarations, or | 
 | 7218 | ///   (2) don't create any shadow decls (or at least don't make them | 
 | 7219 | ///       visible) until we've fully parsed/instantiated the class. | 
 | 7220 | /// The problem with (1) is that we might have to retroactively remove | 
 | 7221 | /// a shadow decl, which requires several O(n) operations because the | 
 | 7222 | /// decl structures are (very reasonably) not designed for removal. | 
 | 7223 | /// (2) avoids this but is very fiddly and phase-dependent. | 
 | 7224 | void Sema::HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow) { | 
| John McCall | 32daa42 | 2010-03-31 01:36:47 +0000 | [diff] [blame] | 7225 |   if (Shadow->getDeclName().getNameKind() == | 
 | 7226 |         DeclarationName::CXXConversionFunctionName) | 
 | 7227 |     cast<CXXRecordDecl>(Shadow->getDeclContext())->removeConversion(Shadow); | 
 | 7228 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7229 |   // Remove it from the DeclContext... | 
 | 7230 |   Shadow->getDeclContext()->removeDecl(Shadow); | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7231 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7232 |   // ...and the scope, if applicable... | 
 | 7233 |   if (S) { | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 7234 |     S->RemoveDecl(Shadow); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7235 |     IdResolver.RemoveDecl(Shadow); | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7236 |   } | 
 | 7237 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7238 |   // ...and the using decl. | 
 | 7239 |   Shadow->getUsingDecl()->removeShadowDecl(Shadow); | 
 | 7240 |  | 
 | 7241 |   // TODO: complain somehow if Shadow was used.  It shouldn't | 
| John McCall | 32daa42 | 2010-03-31 01:36:47 +0000 | [diff] [blame] | 7242 |   // be possible for this to happen, because...? | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7243 | } | 
 | 7244 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 7245 | namespace { | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7246 | class UsingValidatorCCC : public CorrectionCandidateCallback { | 
 | 7247 | public: | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7248 |   UsingValidatorCCC(bool HasTypenameKeyword, bool IsInstantiation) | 
 | 7249 |       : HasTypenameKeyword(HasTypenameKeyword), | 
 | 7250 |         IsInstantiation(IsInstantiation) {} | 
 | 7251 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 7252 |   bool ValidateCandidate(const TypoCorrection &Candidate) LLVM_OVERRIDE { | 
 | 7253 |     NamedDecl *ND = Candidate.getCorrectionDecl(); | 
 | 7254 |  | 
 | 7255 |     // Keywords are not valid here. | 
 | 7256 |     if (!ND || isa<NamespaceDecl>(ND)) | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7257 |       return false; | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 7258 |  | 
 | 7259 |     // Completely unqualified names are invalid for a 'using' declaration. | 
 | 7260 |     if (Candidate.WillReplaceSpecifier() && !Candidate.getCorrectionSpecifier()) | 
 | 7261 |       return false; | 
 | 7262 |  | 
 | 7263 |     if (isa<TypeDecl>(ND)) | 
 | 7264 |       return HasTypenameKeyword || !IsInstantiation; | 
 | 7265 |  | 
 | 7266 |     return !HasTypenameKeyword; | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7267 |   } | 
 | 7268 |  | 
 | 7269 | private: | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7270 |   bool HasTypenameKeyword; | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7271 |   bool IsInstantiation; | 
 | 7272 | }; | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 7273 | } // end anonymous namespace | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7274 |  | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7275 | /// Builds a using declaration. | 
 | 7276 | /// | 
 | 7277 | /// \param IsInstantiation - Whether this call arises from an | 
 | 7278 | ///   instantiation of an unresolved using declaration.  We treat | 
 | 7279 | ///   the lookup differently for these declarations. | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7280 | NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, | 
 | 7281 |                                        SourceLocation UsingLoc, | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 7282 |                                        CXXScopeSpec &SS, | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 7283 |                                        const DeclarationNameInfo &NameInfo, | 
| Anders Carlsson | c72160b | 2009-08-28 05:40:36 +0000 | [diff] [blame] | 7284 |                                        AttributeList *AttrList, | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7285 |                                        bool IsInstantiation, | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7286 |                                        bool HasTypenameKeyword, | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7287 |                                        SourceLocation TypenameLoc) { | 
| Anders Carlsson | c72160b | 2009-08-28 05:40:36 +0000 | [diff] [blame] | 7288 |   assert(!SS.isInvalid() && "Invalid CXXScopeSpec."); | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 7289 |   SourceLocation IdentLoc = NameInfo.getLoc(); | 
| Anders Carlsson | c72160b | 2009-08-28 05:40:36 +0000 | [diff] [blame] | 7290 |   assert(IdentLoc.isValid() && "Invalid TargetName location."); | 
| Eli Friedman | 2a16a13 | 2009-08-27 05:09:36 +0000 | [diff] [blame] | 7291 |  | 
| Anders Carlsson | 550b14b | 2009-08-28 05:49:21 +0000 | [diff] [blame] | 7292 |   // FIXME: We ignore attributes for now. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7293 |  | 
| Anders Carlsson | cf9f921 | 2009-08-28 03:16:11 +0000 | [diff] [blame] | 7294 |   if (SS.isEmpty()) { | 
 | 7295 |     Diag(IdentLoc, diag::err_using_requires_qualname); | 
| Anders Carlsson | c72160b | 2009-08-28 05:40:36 +0000 | [diff] [blame] | 7296 |     return 0; | 
| Anders Carlsson | cf9f921 | 2009-08-28 03:16:11 +0000 | [diff] [blame] | 7297 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7298 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7299 |   // Do the redeclaration lookup in the current scope. | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 7300 |   LookupResult Previous(*this, NameInfo, LookupUsingDeclName, | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7301 |                         ForRedeclaration); | 
 | 7302 |   Previous.setHideTags(false); | 
 | 7303 |   if (S) { | 
 | 7304 |     LookupName(Previous, S); | 
 | 7305 |  | 
 | 7306 |     // It is really dumb that we have to do this. | 
 | 7307 |     LookupResult::Filter F = Previous.makeFilter(); | 
 | 7308 |     while (F.hasNext()) { | 
 | 7309 |       NamedDecl *D = F.next(); | 
 | 7310 |       if (!isDeclInScope(D, CurContext, S)) | 
 | 7311 |         F.erase(); | 
 | 7312 |     } | 
 | 7313 |     F.done(); | 
 | 7314 |   } else { | 
 | 7315 |     assert(IsInstantiation && "no scope in non-instantiation"); | 
 | 7316 |     assert(CurContext->isRecord() && "scope not record in instantiation"); | 
 | 7317 |     LookupQualifiedName(Previous, CurContext); | 
 | 7318 |   } | 
 | 7319 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7320 |   // Check for invalid redeclarations. | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7321 |   if (CheckUsingDeclRedeclaration(UsingLoc, HasTypenameKeyword, | 
 | 7322 |                                   SS, IdentLoc, Previous)) | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7323 |     return 0; | 
 | 7324 |  | 
 | 7325 |   // Check for bad qualifiers. | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7326 |   if (CheckUsingDeclQualifier(UsingLoc, SS, IdentLoc)) | 
 | 7327 |     return 0; | 
 | 7328 |  | 
| John McCall | af8e6ed | 2009-11-12 03:15:40 +0000 | [diff] [blame] | 7329 |   DeclContext *LookupContext = computeDeclContext(SS); | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7330 |   NamedDecl *D; | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7331 |   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); | 
| John McCall | af8e6ed | 2009-11-12 03:15:40 +0000 | [diff] [blame] | 7332 |   if (!LookupContext) { | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7333 |     if (HasTypenameKeyword) { | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7334 |       // FIXME: not all declaration name kinds are legal here | 
 | 7335 |       D = UnresolvedUsingTypenameDecl::Create(Context, CurContext, | 
 | 7336 |                                               UsingLoc, TypenameLoc, | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7337 |                                               QualifierLoc, | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 7338 |                                               IdentLoc, NameInfo.getName()); | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7339 |     } else { | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7340 |       D = UnresolvedUsingValueDecl::Create(Context, CurContext, UsingLoc,  | 
 | 7341 |                                            QualifierLoc, NameInfo); | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7342 |     } | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7343 |   } else { | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7344 |     D = UsingDecl::Create(Context, CurContext, UsingLoc, QualifierLoc, | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7345 |                           NameInfo, HasTypenameKeyword); | 
| Anders Carlsson | 550b14b | 2009-08-28 05:49:21 +0000 | [diff] [blame] | 7346 |   } | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7347 |   D->setAccess(AS); | 
 | 7348 |   CurContext->addDecl(D); | 
 | 7349 |  | 
 | 7350 |   if (!LookupContext) return D; | 
 | 7351 |   UsingDecl *UD = cast<UsingDecl>(D); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7352 |  | 
| John McCall | 77bb1aa | 2010-05-01 00:40:08 +0000 | [diff] [blame] | 7353 |   if (RequireCompleteDeclContext(SS, LookupContext)) { | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7354 |     UD->setInvalidDecl(); | 
 | 7355 |     return UD; | 
| Anders Carlsson | cf9f921 | 2009-08-28 03:16:11 +0000 | [diff] [blame] | 7356 |   } | 
 | 7357 |  | 
| Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 7358 |   // The normal rules do not apply to inheriting constructor declarations. | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 7359 |   if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) { | 
| Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 7360 |     if (CheckInheritingConstructorUsingDecl(UD)) | 
| Sebastian Redl | caa35e4 | 2011-03-12 13:44:32 +0000 | [diff] [blame] | 7361 |       UD->setInvalidDecl(); | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 7362 |     return UD; | 
 | 7363 |   } | 
 | 7364 |  | 
 | 7365 |   // Otherwise, look up the target name. | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7366 |  | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 7367 |   LookupResult R(*this, NameInfo, LookupOrdinaryName); | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7368 |  | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7369 |   // Unlike most lookups, we don't always want to hide tag | 
 | 7370 |   // declarations: tag names are visible through the using declaration | 
 | 7371 |   // even if hidden by ordinary names, *except* in a dependent context | 
 | 7372 |   // where it's important for the sanity of two-phase lookup. | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7373 |   if (!IsInstantiation) | 
 | 7374 |     R.setHideTags(false); | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7375 |  | 
| John McCall | b9abd872 | 2012-04-07 03:04:20 +0000 | [diff] [blame] | 7376 |   // For the purposes of this lookup, we have a base object type | 
 | 7377 |   // equal to that of the current context. | 
 | 7378 |   if (CurContext->isRecord()) { | 
 | 7379 |     R.setBaseObjectType( | 
 | 7380 |                    Context.getTypeDeclType(cast<CXXRecordDecl>(CurContext))); | 
 | 7381 |   } | 
 | 7382 |  | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 7383 |   LookupQualifiedName(R, LookupContext); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7384 |  | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7385 |   // Try to correct typos if possible. | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 7386 |   if (R.empty()) { | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7387 |     UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation); | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7388 |     if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), | 
 | 7389 |                                                R.getLookupKind(), S, &SS, CCC)){ | 
 | 7390 |       // We reject any correction for which ND would be NULL. | 
 | 7391 |       NamedDecl *ND = Corrected.getCorrectionDecl(); | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7392 |       R.setLookupName(Corrected.getCorrection()); | 
 | 7393 |       R.addDecl(ND); | 
| Richard Smith | 2d67097 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 7394 |       // We reject candidates where DroppedSpecifier == true, hence the | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7395 |       // literal '0' below. | 
| Richard Smith | 2d67097 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 7396 |       diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) | 
 | 7397 |                                 << NameInfo.getName() << LookupContext << 0 | 
 | 7398 |                                 << SS.getRange()); | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7399 |     } else { | 
| Richard Smith | 2d67097 | 2013-08-17 00:46:16 +0000 | [diff] [blame] | 7400 |       Diag(IdentLoc, diag::err_no_member) | 
| Kaelyn Uhrain | 0daf1f4 | 2013-07-10 17:34:22 +0000 | [diff] [blame] | 7401 |         << NameInfo.getName() << LookupContext << SS.getRange(); | 
 | 7402 |       UD->setInvalidDecl(); | 
 | 7403 |       return UD; | 
 | 7404 |     } | 
| Douglas Gregor | 9cfbe48 | 2009-06-20 00:51:54 +0000 | [diff] [blame] | 7405 |   } | 
 | 7406 |  | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7407 |   if (R.isAmbiguous()) { | 
 | 7408 |     UD->setInvalidDecl(); | 
 | 7409 |     return UD; | 
 | 7410 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7411 |  | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7412 |   if (HasTypenameKeyword) { | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7413 |     // If we asked for a typename and got a non-type decl, error out. | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7414 |     if (!R.getAsSingle<TypeDecl>()) { | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7415 |       Diag(IdentLoc, diag::err_using_typename_non_type); | 
 | 7416 |       for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) | 
 | 7417 |         Diag((*I)->getUnderlyingDecl()->getLocation(), | 
 | 7418 |              diag::note_using_decl_target); | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7419 |       UD->setInvalidDecl(); | 
 | 7420 |       return UD; | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7421 |     } | 
 | 7422 |   } else { | 
 | 7423 |     // If we asked for a non-typename and we got a type, error out, | 
 | 7424 |     // but only if this is an instantiation of an unresolved using | 
 | 7425 |     // decl.  Otherwise just silently find the type name. | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7426 |     if (IsInstantiation && R.getAsSingle<TypeDecl>()) { | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7427 |       Diag(IdentLoc, diag::err_using_dependent_value_is_type); | 
 | 7428 |       Diag(R.getFoundDecl()->getLocation(), diag::note_using_decl_target); | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7429 |       UD->setInvalidDecl(); | 
 | 7430 |       return UD; | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 7431 |     } | 
| Anders Carlsson | cf9f921 | 2009-08-28 03:16:11 +0000 | [diff] [blame] | 7432 |   } | 
 | 7433 |  | 
| Anders Carlsson | 73b39cf | 2009-08-28 03:35:18 +0000 | [diff] [blame] | 7434 |   // C++0x N2914 [namespace.udecl]p6: | 
 | 7435 |   // A using-declaration shall not name a namespace. | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7436 |   if (R.getAsSingle<NamespaceDecl>()) { | 
| Anders Carlsson | 73b39cf | 2009-08-28 03:35:18 +0000 | [diff] [blame] | 7437 |     Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace) | 
 | 7438 |       << SS.getRange(); | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7439 |     UD->setInvalidDecl(); | 
 | 7440 |     return UD; | 
| Anders Carlsson | 73b39cf | 2009-08-28 03:35:18 +0000 | [diff] [blame] | 7441 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7442 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7443 |   for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { | 
 | 7444 |     if (!CheckUsingShadowDecl(UD, *I, Previous)) | 
 | 7445 |       BuildUsingShadowDecl(S, UD, *I); | 
 | 7446 |   } | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 7447 |  | 
 | 7448 |   return UD; | 
| Douglas Gregor | 9cfbe48 | 2009-06-20 00:51:54 +0000 | [diff] [blame] | 7449 | } | 
 | 7450 |  | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 7451 | /// Additional checks for a using declaration referring to a constructor name. | 
| Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 7452 | bool Sema::CheckInheritingConstructorUsingDecl(UsingDecl *UD) { | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7453 |   assert(!UD->hasTypename() && "expecting a constructor name"); | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 7454 |  | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7455 |   const Type *SourceType = UD->getQualifier()->getAsType(); | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 7456 |   assert(SourceType && | 
 | 7457 |          "Using decl naming constructor doesn't have type in scope spec."); | 
 | 7458 |   CXXRecordDecl *TargetClass = cast<CXXRecordDecl>(CurContext); | 
 | 7459 |  | 
 | 7460 |   // Check whether the named type is a direct base class. | 
 | 7461 |   CanQualType CanonicalSourceType = SourceType->getCanonicalTypeUnqualified(); | 
 | 7462 |   CXXRecordDecl::base_class_iterator BaseIt, BaseE; | 
 | 7463 |   for (BaseIt = TargetClass->bases_begin(), BaseE = TargetClass->bases_end(); | 
 | 7464 |        BaseIt != BaseE; ++BaseIt) { | 
 | 7465 |     CanQualType BaseType = BaseIt->getType()->getCanonicalTypeUnqualified(); | 
 | 7466 |     if (CanonicalSourceType == BaseType) | 
 | 7467 |       break; | 
| Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 7468 |     if (BaseIt->getType()->isDependentType()) | 
 | 7469 |       break; | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 7470 |   } | 
 | 7471 |  | 
 | 7472 |   if (BaseIt == BaseE) { | 
 | 7473 |     // Did not find SourceType in the bases. | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7474 |     Diag(UD->getUsingLoc(), | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 7475 |          diag::err_using_decl_constructor_not_in_direct_base) | 
 | 7476 |       << UD->getNameInfo().getSourceRange() | 
 | 7477 |       << QualType(SourceType, 0) << TargetClass; | 
 | 7478 |     return true; | 
 | 7479 |   } | 
 | 7480 |  | 
| Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 7481 |   if (!CurContext->isDependentContext()) | 
 | 7482 |     BaseIt->setInheritConstructors(); | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 7483 |  | 
 | 7484 |   return false; | 
 | 7485 | } | 
 | 7486 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7487 | /// Checks that the given using declaration is not an invalid | 
 | 7488 | /// redeclaration.  Note that this is checking only for the using decl | 
 | 7489 | /// itself, not for any ill-formedness among the UsingShadowDecls. | 
 | 7490 | bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc, | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7491 |                                        bool HasTypenameKeyword, | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7492 |                                        const CXXScopeSpec &SS, | 
 | 7493 |                                        SourceLocation NameLoc, | 
 | 7494 |                                        const LookupResult &Prev) { | 
 | 7495 |   // C++03 [namespace.udecl]p8: | 
 | 7496 |   // C++0x [namespace.udecl]p10: | 
 | 7497 |   //   A using-declaration is a declaration and can therefore be used | 
 | 7498 |   //   repeatedly where (and only where) multiple declarations are | 
 | 7499 |   //   allowed. | 
| Douglas Gregor | a97badf | 2010-05-06 23:31:27 +0000 | [diff] [blame] | 7500 |   // | 
| John McCall | 8a72621 | 2010-11-29 18:01:58 +0000 | [diff] [blame] | 7501 |   // That's in non-member contexts. | 
 | 7502 |   if (!CurContext->getRedeclContext()->isRecord()) | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7503 |     return false; | 
 | 7504 |  | 
 | 7505 |   NestedNameSpecifier *Qual | 
 | 7506 |     = static_cast<NestedNameSpecifier*>(SS.getScopeRep()); | 
 | 7507 |  | 
 | 7508 |   for (LookupResult::iterator I = Prev.begin(), E = Prev.end(); I != E; ++I) { | 
 | 7509 |     NamedDecl *D = *I; | 
 | 7510 |  | 
 | 7511 |     bool DTypename; | 
 | 7512 |     NestedNameSpecifier *DQual; | 
 | 7513 |     if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) { | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7514 |       DTypename = UD->hasTypename(); | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7515 |       DQual = UD->getQualifier(); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7516 |     } else if (UnresolvedUsingValueDecl *UD | 
 | 7517 |                  = dyn_cast<UnresolvedUsingValueDecl>(D)) { | 
 | 7518 |       DTypename = false; | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7519 |       DQual = UD->getQualifier(); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7520 |     } else if (UnresolvedUsingTypenameDecl *UD | 
 | 7521 |                  = dyn_cast<UnresolvedUsingTypenameDecl>(D)) { | 
 | 7522 |       DTypename = true; | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 7523 |       DQual = UD->getQualifier(); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7524 |     } else continue; | 
 | 7525 |  | 
 | 7526 |     // using decls differ if one says 'typename' and the other doesn't. | 
 | 7527 |     // FIXME: non-dependent using decls? | 
| Enea Zaffanella | 8d030c7 | 2013-07-22 10:54:09 +0000 | [diff] [blame] | 7528 |     if (HasTypenameKeyword != DTypename) continue; | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7529 |  | 
 | 7530 |     // using decls differ if they name different scopes (but note that | 
 | 7531 |     // template instantiation can cause this check to trigger when it | 
 | 7532 |     // didn't before instantiation). | 
 | 7533 |     if (Context.getCanonicalNestedNameSpecifier(Qual) != | 
 | 7534 |         Context.getCanonicalNestedNameSpecifier(DQual)) | 
 | 7535 |       continue; | 
 | 7536 |  | 
 | 7537 |     Diag(NameLoc, diag::err_using_decl_redeclaration) << SS.getRange(); | 
| John McCall | 41ce66f | 2009-12-10 19:51:03 +0000 | [diff] [blame] | 7538 |     Diag(D->getLocation(), diag::note_using_decl) << 1; | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 7539 |     return true; | 
 | 7540 |   } | 
 | 7541 |  | 
 | 7542 |   return false; | 
 | 7543 | } | 
 | 7544 |  | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7545 |  | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7546 | /// Checks that the given nested-name qualifier used in a using decl | 
 | 7547 | /// in the current context is appropriately related to the current | 
 | 7548 | /// scope.  If an error is found, diagnoses it and returns true. | 
 | 7549 | bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc, | 
 | 7550 |                                    const CXXScopeSpec &SS, | 
 | 7551 |                                    SourceLocation NameLoc) { | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7552 |   DeclContext *NamedContext = computeDeclContext(SS); | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7553 |  | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7554 |   if (!CurContext->isRecord()) { | 
 | 7555 |     // C++03 [namespace.udecl]p3: | 
 | 7556 |     // C++0x [namespace.udecl]p8: | 
 | 7557 |     //   A using-declaration for a class member shall be a member-declaration. | 
 | 7558 |  | 
 | 7559 |     // If we weren't able to compute a valid scope, it must be a | 
 | 7560 |     // dependent class scope. | 
 | 7561 |     if (!NamedContext || NamedContext->isRecord()) { | 
 | 7562 |       Diag(NameLoc, diag::err_using_decl_can_not_refer_to_class_member) | 
 | 7563 |         << SS.getRange(); | 
 | 7564 |       return true; | 
 | 7565 |     } | 
 | 7566 |  | 
 | 7567 |     // Otherwise, everything is known to be fine. | 
 | 7568 |     return false; | 
 | 7569 |   } | 
 | 7570 |  | 
 | 7571 |   // The current scope is a record. | 
 | 7572 |  | 
 | 7573 |   // If the named context is dependent, we can't decide much. | 
 | 7574 |   if (!NamedContext) { | 
 | 7575 |     // FIXME: in C++0x, we can diagnose if we can prove that the | 
 | 7576 |     // nested-name-specifier does not refer to a base class, which is | 
 | 7577 |     // still possible in some cases. | 
 | 7578 |  | 
 | 7579 |     // Otherwise we have to conservatively report that things might be | 
 | 7580 |     // okay. | 
 | 7581 |     return false; | 
 | 7582 |   } | 
 | 7583 |  | 
 | 7584 |   if (!NamedContext->isRecord()) { | 
 | 7585 |     // Ideally this would point at the last name in the specifier, | 
 | 7586 |     // but we don't have that level of source info. | 
 | 7587 |     Diag(SS.getRange().getBegin(), | 
 | 7588 |          diag::err_using_decl_nested_name_specifier_is_not_class) | 
 | 7589 |       << (NestedNameSpecifier*) SS.getScopeRep() << SS.getRange(); | 
 | 7590 |     return true; | 
 | 7591 |   } | 
 | 7592 |  | 
| Douglas Gregor | 6fb0729 | 2010-12-21 07:41:49 +0000 | [diff] [blame] | 7593 |   if (!NamedContext->isDependentContext() && | 
 | 7594 |       RequireCompleteDeclContext(const_cast<CXXScopeSpec&>(SS), NamedContext)) | 
 | 7595 |     return true; | 
 | 7596 |  | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 7597 |   if (getLangOpts().CPlusPlus11) { | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7598 |     // C++0x [namespace.udecl]p3: | 
 | 7599 |     //   In a using-declaration used as a member-declaration, the | 
 | 7600 |     //   nested-name-specifier shall name a base class of the class | 
 | 7601 |     //   being defined. | 
 | 7602 |  | 
 | 7603 |     if (cast<CXXRecordDecl>(CurContext)->isProvablyNotDerivedFrom( | 
 | 7604 |                                  cast<CXXRecordDecl>(NamedContext))) { | 
 | 7605 |       if (CurContext == NamedContext) { | 
 | 7606 |         Diag(NameLoc, | 
 | 7607 |              diag::err_using_decl_nested_name_specifier_is_current_class) | 
 | 7608 |           << SS.getRange(); | 
 | 7609 |         return true; | 
 | 7610 |       } | 
 | 7611 |  | 
 | 7612 |       Diag(SS.getRange().getBegin(), | 
 | 7613 |            diag::err_using_decl_nested_name_specifier_is_not_base_class) | 
 | 7614 |         << (NestedNameSpecifier*) SS.getScopeRep() | 
 | 7615 |         << cast<CXXRecordDecl>(CurContext) | 
 | 7616 |         << SS.getRange(); | 
 | 7617 |       return true; | 
 | 7618 |     } | 
 | 7619 |  | 
 | 7620 |     return false; | 
 | 7621 |   } | 
 | 7622 |  | 
 | 7623 |   // C++03 [namespace.udecl]p4: | 
 | 7624 |   //   A using-declaration used as a member-declaration shall refer | 
 | 7625 |   //   to a member of a base class of the class being defined [etc.]. | 
 | 7626 |  | 
 | 7627 |   // Salient point: SS doesn't have to name a base class as long as | 
 | 7628 |   // lookup only finds members from base classes.  Therefore we can | 
 | 7629 |   // diagnose here only if we can prove that that can't happen, | 
 | 7630 |   // i.e. if the class hierarchies provably don't intersect. | 
 | 7631 |  | 
 | 7632 |   // TODO: it would be nice if "definitely valid" results were cached | 
 | 7633 |   // in the UsingDecl and UsingShadowDecl so that these checks didn't | 
 | 7634 |   // need to be repeated. | 
 | 7635 |  | 
 | 7636 |   struct UserData { | 
| Benjamin Kramer | 8c43dcc | 2012-02-23 16:06:01 +0000 | [diff] [blame] | 7637 |     llvm::SmallPtrSet<const CXXRecordDecl*, 4> Bases; | 
| John McCall | 604e7f1 | 2009-12-08 07:46:18 +0000 | [diff] [blame] | 7638 |  | 
 | 7639 |     static bool collect(const CXXRecordDecl *Base, void *OpaqueData) { | 
 | 7640 |       UserData *Data = reinterpret_cast<UserData*>(OpaqueData); | 
 | 7641 |       Data->Bases.insert(Base); | 
 | 7642 |       return true; | 
 | 7643 |     } | 
 | 7644 |  | 
 | 7645 |     bool hasDependentBases(const CXXRecordDecl *Class) { | 
 | 7646 |       return !Class->forallBases(collect, this); | 
 | 7647 |     } | 
 | 7648 |  | 
 | 7649 |     /// Returns true if the base is dependent or is one of the | 
 | 7650 |     /// accumulated base classes. | 
 | 7651 |     static bool doesNotContain(const CXXRecordDecl *Base, void *OpaqueData) { | 
 | 7652 |       UserData *Data = reinterpret_cast<UserData*>(OpaqueData); | 
 | 7653 |       return !Data->Bases.count(Base); | 
 | 7654 |     } | 
 | 7655 |  | 
 | 7656 |     bool mightShareBases(const CXXRecordDecl *Class) { | 
 | 7657 |       return Bases.count(Class) || !Class->forallBases(doesNotContain, this); | 
 | 7658 |     } | 
 | 7659 |   }; | 
 | 7660 |  | 
 | 7661 |   UserData Data; | 
 | 7662 |  | 
 | 7663 |   // Returns false if we find a dependent base. | 
 | 7664 |   if (Data.hasDependentBases(cast<CXXRecordDecl>(CurContext))) | 
 | 7665 |     return false; | 
 | 7666 |  | 
 | 7667 |   // Returns false if the class has a dependent base or if it or one | 
 | 7668 |   // of its bases is present in the base set of the current context. | 
 | 7669 |   if (Data.mightShareBases(cast<CXXRecordDecl>(NamedContext))) | 
 | 7670 |     return false; | 
 | 7671 |  | 
 | 7672 |   Diag(SS.getRange().getBegin(), | 
 | 7673 |        diag::err_using_decl_nested_name_specifier_is_not_base_class) | 
 | 7674 |     << (NestedNameSpecifier*) SS.getScopeRep() | 
 | 7675 |     << cast<CXXRecordDecl>(CurContext) | 
 | 7676 |     << SS.getRange(); | 
 | 7677 |  | 
 | 7678 |   return true; | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 7679 | } | 
 | 7680 |  | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7681 | Decl *Sema::ActOnAliasDeclaration(Scope *S, | 
 | 7682 |                                   AccessSpecifier AS, | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7683 |                                   MultiTemplateParamsArg TemplateParamLists, | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7684 |                                   SourceLocation UsingLoc, | 
 | 7685 |                                   UnqualifiedId &Name, | 
| Richard Smith | 6b3d3e5 | 2013-02-20 19:22:51 +0000 | [diff] [blame] | 7686 |                                   AttributeList *AttrList, | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7687 |                                   TypeResult Type) { | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7688 |   // Skip up to the relevant declaration scope. | 
 | 7689 |   while (S->getFlags() & Scope::TemplateParamScope) | 
 | 7690 |     S = S->getParent(); | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7691 |   assert((S->getFlags() & Scope::DeclScope) && | 
 | 7692 |          "got alias-declaration outside of declaration scope"); | 
 | 7693 |  | 
 | 7694 |   if (Type.isInvalid()) | 
 | 7695 |     return 0; | 
 | 7696 |  | 
 | 7697 |   bool Invalid = false; | 
 | 7698 |   DeclarationNameInfo NameInfo = GetNameFromUnqualifiedId(Name); | 
 | 7699 |   TypeSourceInfo *TInfo = 0; | 
| Nick Lewycky | b79bf1d | 2011-05-02 01:07:19 +0000 | [diff] [blame] | 7700 |   GetTypeFromParser(Type.get(), &TInfo); | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7701 |  | 
 | 7702 |   if (DiagnoseClassNameShadow(CurContext, NameInfo)) | 
 | 7703 |     return 0; | 
 | 7704 |  | 
 | 7705 |   if (DiagnoseUnexpandedParameterPack(Name.StartLocation, TInfo, | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7706 |                                       UPPC_DeclarationType)) { | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7707 |     Invalid = true; | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7708 |     TInfo = Context.getTrivialTypeSourceInfo(Context.IntTy,  | 
 | 7709 |                                              TInfo->getTypeLoc().getBeginLoc()); | 
 | 7710 |   } | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7711 |  | 
 | 7712 |   LookupResult Previous(*this, NameInfo, LookupOrdinaryName, ForRedeclaration); | 
 | 7713 |   LookupName(Previous, S); | 
 | 7714 |  | 
 | 7715 |   // Warn about shadowing the name of a template parameter. | 
 | 7716 |   if (Previous.isSingleResult() && | 
 | 7717 |       Previous.getFoundDecl()->isTemplateParameter()) { | 
| Douglas Gregor | cb8f951 | 2011-10-20 17:58:49 +0000 | [diff] [blame] | 7718 |     DiagnoseTemplateParameterShadow(Name.StartLocation,Previous.getFoundDecl()); | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7719 |     Previous.clear(); | 
 | 7720 |   } | 
 | 7721 |  | 
 | 7722 |   assert(Name.Kind == UnqualifiedId::IK_Identifier && | 
 | 7723 |          "name in alias declaration must be an identifier"); | 
 | 7724 |   TypeAliasDecl *NewTD = TypeAliasDecl::Create(Context, CurContext, UsingLoc, | 
 | 7725 |                                                Name.StartLocation, | 
 | 7726 |                                                Name.Identifier, TInfo); | 
 | 7727 |  | 
 | 7728 |   NewTD->setAccess(AS); | 
 | 7729 |  | 
 | 7730 |   if (Invalid) | 
 | 7731 |     NewTD->setInvalidDecl(); | 
 | 7732 |  | 
| Richard Smith | 6b3d3e5 | 2013-02-20 19:22:51 +0000 | [diff] [blame] | 7733 |   ProcessDeclAttributeList(S, NewTD, AttrList); | 
 | 7734 |  | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7735 |   CheckTypedefForVariablyModifiedType(S, NewTD); | 
 | 7736 |   Invalid |= NewTD->isInvalidDecl(); | 
 | 7737 |  | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7738 |   bool Redeclaration = false; | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7739 |  | 
 | 7740 |   NamedDecl *NewND; | 
 | 7741 |   if (TemplateParamLists.size()) { | 
 | 7742 |     TypeAliasTemplateDecl *OldDecl = 0; | 
 | 7743 |     TemplateParameterList *OldTemplateParams = 0; | 
 | 7744 |  | 
 | 7745 |     if (TemplateParamLists.size() != 1) { | 
 | 7746 |       Diag(UsingLoc, diag::err_alias_template_extra_headers) | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 7747 |         << SourceRange(TemplateParamLists[1]->getTemplateLoc(), | 
 | 7748 |          TemplateParamLists[TemplateParamLists.size()-1]->getRAngleLoc()); | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7749 |     } | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 7750 |     TemplateParameterList *TemplateParams = TemplateParamLists[0]; | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7751 |  | 
 | 7752 |     // Only consider previous declarations in the same scope. | 
 | 7753 |     FilterLookupForScope(Previous, CurContext, S, /*ConsiderLinkage*/false, | 
 | 7754 |                          /*ExplicitInstantiationOrSpecialization*/false); | 
 | 7755 |     if (!Previous.empty()) { | 
 | 7756 |       Redeclaration = true; | 
 | 7757 |  | 
 | 7758 |       OldDecl = Previous.getAsSingle<TypeAliasTemplateDecl>(); | 
 | 7759 |       if (!OldDecl && !Invalid) { | 
 | 7760 |         Diag(UsingLoc, diag::err_redefinition_different_kind) | 
 | 7761 |           << Name.Identifier; | 
 | 7762 |  | 
 | 7763 |         NamedDecl *OldD = Previous.getRepresentativeDecl(); | 
 | 7764 |         if (OldD->getLocation().isValid()) | 
 | 7765 |           Diag(OldD->getLocation(), diag::note_previous_definition); | 
 | 7766 |  | 
 | 7767 |         Invalid = true; | 
 | 7768 |       } | 
 | 7769 |  | 
 | 7770 |       if (!Invalid && OldDecl && !OldDecl->isInvalidDecl()) { | 
 | 7771 |         if (TemplateParameterListsAreEqual(TemplateParams, | 
 | 7772 |                                            OldDecl->getTemplateParameters(), | 
 | 7773 |                                            /*Complain=*/true, | 
 | 7774 |                                            TPL_TemplateMatch)) | 
 | 7775 |           OldTemplateParams = OldDecl->getTemplateParameters(); | 
 | 7776 |         else | 
 | 7777 |           Invalid = true; | 
 | 7778 |  | 
 | 7779 |         TypeAliasDecl *OldTD = OldDecl->getTemplatedDecl(); | 
 | 7780 |         if (!Invalid && | 
 | 7781 |             !Context.hasSameType(OldTD->getUnderlyingType(), | 
 | 7782 |                                  NewTD->getUnderlyingType())) { | 
 | 7783 |           // FIXME: The C++0x standard does not clearly say this is ill-formed, | 
 | 7784 |           // but we can't reasonably accept it. | 
 | 7785 |           Diag(NewTD->getLocation(), diag::err_redefinition_different_typedef) | 
 | 7786 |             << 2 << NewTD->getUnderlyingType() << OldTD->getUnderlyingType(); | 
 | 7787 |           if (OldTD->getLocation().isValid()) | 
 | 7788 |             Diag(OldTD->getLocation(), diag::note_previous_definition); | 
 | 7789 |           Invalid = true; | 
 | 7790 |         } | 
 | 7791 |       } | 
 | 7792 |     } | 
 | 7793 |  | 
 | 7794 |     // Merge any previous default template arguments into our parameters, | 
 | 7795 |     // and check the parameter list. | 
 | 7796 |     if (CheckTemplateParameterList(TemplateParams, OldTemplateParams, | 
 | 7797 |                                    TPC_TypeAliasTemplate)) | 
 | 7798 |       return 0; | 
 | 7799 |  | 
 | 7800 |     TypeAliasTemplateDecl *NewDecl = | 
 | 7801 |       TypeAliasTemplateDecl::Create(Context, CurContext, UsingLoc, | 
 | 7802 |                                     Name.Identifier, TemplateParams, | 
 | 7803 |                                     NewTD); | 
 | 7804 |  | 
 | 7805 |     NewDecl->setAccess(AS); | 
 | 7806 |  | 
 | 7807 |     if (Invalid) | 
 | 7808 |       NewDecl->setInvalidDecl(); | 
 | 7809 |     else if (OldDecl) | 
 | 7810 |       NewDecl->setPreviousDeclaration(OldDecl); | 
 | 7811 |  | 
 | 7812 |     NewND = NewDecl; | 
 | 7813 |   } else { | 
 | 7814 |     ActOnTypedefNameDecl(S, CurContext, NewTD, Previous, Redeclaration); | 
 | 7815 |     NewND = NewTD; | 
 | 7816 |   } | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7817 |  | 
 | 7818 |   if (!Redeclaration) | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7819 |     PushOnScopeChains(NewND, S); | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7820 |  | 
| Dmitri Gribenko | c27bc80 | 2012-08-02 20:49:51 +0000 | [diff] [blame] | 7821 |   ActOnDocumentableDecl(NewND); | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 7822 |   return NewND; | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 7823 | } | 
 | 7824 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 7825 | Decl *Sema::ActOnNamespaceAliasDef(Scope *S, | 
| Anders Carlsson | 03bd5a1 | 2009-03-28 22:53:22 +0000 | [diff] [blame] | 7826 |                                              SourceLocation NamespaceLoc, | 
| Chris Lattner | b28317a | 2009-03-28 19:18:32 +0000 | [diff] [blame] | 7827 |                                              SourceLocation AliasLoc, | 
 | 7828 |                                              IdentifierInfo *Alias, | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 7829 |                                              CXXScopeSpec &SS, | 
| Anders Carlsson | 03bd5a1 | 2009-03-28 22:53:22 +0000 | [diff] [blame] | 7830 |                                              SourceLocation IdentLoc, | 
 | 7831 |                                              IdentifierInfo *Ident) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7832 |  | 
| Anders Carlsson | 81c85c4 | 2009-03-28 23:53:49 +0000 | [diff] [blame] | 7833 |   // Lookup the namespace name. | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 7834 |   LookupResult R(*this, Ident, IdentLoc, LookupNamespaceName); | 
 | 7835 |   LookupParsedName(R, S, &SS); | 
| Anders Carlsson | 81c85c4 | 2009-03-28 23:53:49 +0000 | [diff] [blame] | 7836 |  | 
| Anders Carlsson | 8d7ba40 | 2009-03-28 06:23:46 +0000 | [diff] [blame] | 7837 |   // Check if we have a previous declaration with the same name. | 
| Douglas Gregor | ae37475 | 2010-05-03 15:37:31 +0000 | [diff] [blame] | 7838 |   NamedDecl *PrevDecl | 
 | 7839 |     = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName,  | 
 | 7840 |                        ForRedeclaration); | 
 | 7841 |   if (PrevDecl && !isDeclInScope(PrevDecl, CurContext, S)) | 
 | 7842 |     PrevDecl = 0; | 
 | 7843 |  | 
 | 7844 |   if (PrevDecl) { | 
| Anders Carlsson | 81c85c4 | 2009-03-28 23:53:49 +0000 | [diff] [blame] | 7845 |     if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7846 |       // We already have an alias with the same name that points to the same | 
| Anders Carlsson | 81c85c4 | 2009-03-28 23:53:49 +0000 | [diff] [blame] | 7847 |       // namespace, so don't create a new one. | 
| Douglas Gregor | c67b032 | 2010-03-26 22:59:39 +0000 | [diff] [blame] | 7848 |       // FIXME: At some point, we'll want to create the (redundant) | 
 | 7849 |       // declaration to maintain better source information. | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 7850 |       if (!R.isAmbiguous() && !R.empty() && | 
| Douglas Gregor | c67b032 | 2010-03-26 22:59:39 +0000 | [diff] [blame] | 7851 |           AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl()))) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 7852 |         return 0; | 
| Anders Carlsson | 81c85c4 | 2009-03-28 23:53:49 +0000 | [diff] [blame] | 7853 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7854 |  | 
| Anders Carlsson | 8d7ba40 | 2009-03-28 06:23:46 +0000 | [diff] [blame] | 7855 |     unsigned DiagID = isa<NamespaceDecl>(PrevDecl) ? diag::err_redefinition : | 
 | 7856 |       diag::err_redefinition_different_kind; | 
 | 7857 |     Diag(AliasLoc, DiagID) << Alias; | 
 | 7858 |     Diag(PrevDecl->getLocation(), diag::note_previous_definition); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 7859 |     return 0; | 
| Anders Carlsson | 8d7ba40 | 2009-03-28 06:23:46 +0000 | [diff] [blame] | 7860 |   } | 
 | 7861 |  | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 7862 |   if (R.isAmbiguous()) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 7863 |     return 0; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7864 |  | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 7865 |   if (R.empty()) { | 
| Douglas Gregor | d8bba9c | 2011-06-28 16:20:02 +0000 | [diff] [blame] | 7866 |     if (!TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, Ident)) { | 
| Richard Smith | bf9658c | 2012-04-05 23:13:23 +0000 | [diff] [blame] | 7867 |       Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange(); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 7868 |       return 0; | 
| Douglas Gregor | 0e8c4b9 | 2010-06-29 18:55:19 +0000 | [diff] [blame] | 7869 |     } | 
| Anders Carlsson | 5721c68 | 2009-03-28 06:42:02 +0000 | [diff] [blame] | 7870 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7871 |  | 
| Fariborz Jahanian | f8dcb86 | 2009-06-19 19:55:27 +0000 | [diff] [blame] | 7872 |   NamespaceAliasDecl *AliasDecl = | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7873 |     NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc, | 
| Douglas Gregor | 0cfaf6a | 2011-02-25 17:08:07 +0000 | [diff] [blame] | 7874 |                                Alias, SS.getWithLocInContext(Context), | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 7875 |                                IdentLoc, R.getFoundDecl()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 7876 |  | 
| John McCall | 3dbd3d5 | 2010-02-16 06:53:13 +0000 | [diff] [blame] | 7877 |   PushOnScopeChains(AliasDecl, S); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 7878 |   return AliasDecl; | 
| Anders Carlsson | dbb0094 | 2009-03-28 05:27:17 +0000 | [diff] [blame] | 7879 | } | 
 | 7880 |  | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 7881 | Sema::ImplicitExceptionSpecification | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 7882 | Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc, | 
 | 7883 |                                                CXXMethodDecl *MD) { | 
 | 7884 |   CXXRecordDecl *ClassDecl = MD->getParent(); | 
 | 7885 |  | 
| Douglas Gregor | eb8c670 | 2010-07-01 22:31:05 +0000 | [diff] [blame] | 7886 |   // C++ [except.spec]p14: | 
 | 7887 |   //   An implicitly declared special member function (Clause 12) shall have an  | 
 | 7888 |   //   exception-specification. [...] | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 7889 |   ImplicitExceptionSpecification ExceptSpec(*this); | 
| Abramo Bagnara | cdb8076 | 2011-07-11 08:52:40 +0000 | [diff] [blame] | 7890 |   if (ClassDecl->isInvalidDecl()) | 
 | 7891 |     return ExceptSpec; | 
| Douglas Gregor | eb8c670 | 2010-07-01 22:31:05 +0000 | [diff] [blame] | 7892 |  | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 7893 |   // Direct base-class constructors. | 
| Douglas Gregor | eb8c670 | 2010-07-01 22:31:05 +0000 | [diff] [blame] | 7894 |   for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(), | 
 | 7895 |                                        BEnd = ClassDecl->bases_end(); | 
 | 7896 |        B != BEnd; ++B) { | 
 | 7897 |     if (B->isVirtual()) // Handled below. | 
 | 7898 |       continue; | 
 | 7899 |      | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 7900 |     if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) { | 
 | 7901 |       CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); | 
| Sean Hunt | b320e0c | 2011-06-10 03:50:41 +0000 | [diff] [blame] | 7902 |       CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl); | 
 | 7903 |       // If this is a deleted function, add it anyway. This might be conformant | 
 | 7904 |       // with the standard. This might not. I'm not sure. It might not matter. | 
 | 7905 |       if (Constructor) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 7906 |         ExceptSpec.CalledDecl(B->getLocStart(), Constructor); | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 7907 |     } | 
| Douglas Gregor | eb8c670 | 2010-07-01 22:31:05 +0000 | [diff] [blame] | 7908 |   } | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 7909 |  | 
 | 7910 |   // Virtual base-class constructors. | 
| Douglas Gregor | eb8c670 | 2010-07-01 22:31:05 +0000 | [diff] [blame] | 7911 |   for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(), | 
 | 7912 |                                        BEnd = ClassDecl->vbases_end(); | 
 | 7913 |        B != BEnd; ++B) { | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 7914 |     if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) { | 
 | 7915 |       CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); | 
| Sean Hunt | b320e0c | 2011-06-10 03:50:41 +0000 | [diff] [blame] | 7916 |       CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl); | 
 | 7917 |       // If this is a deleted function, add it anyway. This might be conformant | 
 | 7918 |       // with the standard. This might not. I'm not sure. It might not matter. | 
 | 7919 |       if (Constructor) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 7920 |         ExceptSpec.CalledDecl(B->getLocStart(), Constructor); | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 7921 |     } | 
| Douglas Gregor | eb8c670 | 2010-07-01 22:31:05 +0000 | [diff] [blame] | 7922 |   } | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 7923 |  | 
 | 7924 |   // Field constructors. | 
| Douglas Gregor | eb8c670 | 2010-07-01 22:31:05 +0000 | [diff] [blame] | 7925 |   for (RecordDecl::field_iterator F = ClassDecl->field_begin(), | 
 | 7926 |                                FEnd = ClassDecl->field_end(); | 
 | 7927 |        F != FEnd; ++F) { | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 7928 |     if (F->hasInClassInitializer()) { | 
 | 7929 |       if (Expr *E = F->getInClassInitializer()) | 
 | 7930 |         ExceptSpec.CalledExpr(E); | 
 | 7931 |       else if (!F->isInvalidDecl()) | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 7932 |         // DR1351: | 
 | 7933 |         //   If the brace-or-equal-initializer of a non-static data member | 
 | 7934 |         //   invokes a defaulted default constructor of its class or of an | 
 | 7935 |         //   enclosing class in a potentially evaluated subexpression, the | 
 | 7936 |         //   program is ill-formed. | 
 | 7937 |         // | 
 | 7938 |         // This resolution is unworkable: the exception specification of the | 
 | 7939 |         // default constructor can be needed in an unevaluated context, in | 
 | 7940 |         // particular, in the operand of a noexcept-expression, and we can be | 
 | 7941 |         // unable to compute an exception specification for an enclosed class. | 
 | 7942 |         // | 
 | 7943 |         // We do not allow an in-class initializer to require the evaluation | 
 | 7944 |         // of the exception specification for any in-class initializer whose | 
 | 7945 |         // definition is not lexically complete. | 
 | 7946 |         Diag(Loc, diag::err_in_class_initializer_references_def_ctor) << MD; | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 7947 |     } else if (const RecordType *RecordTy | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 7948 |               = Context.getBaseElementType(F->getType())->getAs<RecordType>()) { | 
| Sean Hunt | b320e0c | 2011-06-10 03:50:41 +0000 | [diff] [blame] | 7949 |       CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); | 
 | 7950 |       CXXConstructorDecl *Constructor = LookupDefaultConstructor(FieldRecDecl); | 
 | 7951 |       // If this is a deleted function, add it anyway. This might be conformant | 
 | 7952 |       // with the standard. This might not. I'm not sure. It might not matter. | 
 | 7953 |       // In particular, the problem is that this function never gets called. It | 
 | 7954 |       // might just be ill-formed because this function attempts to refer to | 
 | 7955 |       // a deleted function here. | 
 | 7956 |       if (Constructor) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 7957 |         ExceptSpec.CalledDecl(F->getLocation(), Constructor); | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 7958 |     } | 
| Douglas Gregor | eb8c670 | 2010-07-01 22:31:05 +0000 | [diff] [blame] | 7959 |   } | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 7960 |  | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 7961 |   return ExceptSpec; | 
 | 7962 | } | 
 | 7963 |  | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 7964 | Sema::ImplicitExceptionSpecification | 
| Richard Smith | 0b0ca47 | 2013-04-10 06:11:48 +0000 | [diff] [blame] | 7965 | Sema::ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD) { | 
 | 7966 |   CXXRecordDecl *ClassDecl = CD->getParent(); | 
 | 7967 |  | 
 | 7968 |   // C++ [except.spec]p14: | 
 | 7969 |   //   An inheriting constructor [...] shall have an exception-specification. [...] | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 7970 |   ImplicitExceptionSpecification ExceptSpec(*this); | 
| Richard Smith | 0b0ca47 | 2013-04-10 06:11:48 +0000 | [diff] [blame] | 7971 |   if (ClassDecl->isInvalidDecl()) | 
 | 7972 |     return ExceptSpec; | 
 | 7973 |  | 
 | 7974 |   // Inherited constructor. | 
 | 7975 |   const CXXConstructorDecl *InheritedCD = CD->getInheritedConstructor(); | 
 | 7976 |   const CXXRecordDecl *InheritedDecl = InheritedCD->getParent(); | 
 | 7977 |   // FIXME: Copying or moving the parameters could add extra exceptions to the | 
 | 7978 |   // set, as could the default arguments for the inherited constructor. This | 
 | 7979 |   // will be addressed when we implement the resolution of core issue 1351. | 
 | 7980 |   ExceptSpec.CalledDecl(CD->getLocStart(), InheritedCD); | 
 | 7981 |  | 
 | 7982 |   // Direct base-class constructors. | 
 | 7983 |   for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(), | 
 | 7984 |                                        BEnd = ClassDecl->bases_end(); | 
 | 7985 |        B != BEnd; ++B) { | 
 | 7986 |     if (B->isVirtual()) // Handled below. | 
 | 7987 |       continue; | 
 | 7988 |  | 
 | 7989 |     if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) { | 
 | 7990 |       CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); | 
 | 7991 |       if (BaseClassDecl == InheritedDecl) | 
 | 7992 |         continue; | 
 | 7993 |       CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl); | 
 | 7994 |       if (Constructor) | 
 | 7995 |         ExceptSpec.CalledDecl(B->getLocStart(), Constructor); | 
 | 7996 |     } | 
 | 7997 |   } | 
 | 7998 |  | 
 | 7999 |   // Virtual base-class constructors. | 
 | 8000 |   for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(), | 
 | 8001 |                                        BEnd = ClassDecl->vbases_end(); | 
 | 8002 |        B != BEnd; ++B) { | 
 | 8003 |     if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) { | 
 | 8004 |       CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); | 
 | 8005 |       if (BaseClassDecl == InheritedDecl) | 
 | 8006 |         continue; | 
 | 8007 |       CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl); | 
 | 8008 |       if (Constructor) | 
 | 8009 |         ExceptSpec.CalledDecl(B->getLocStart(), Constructor); | 
 | 8010 |     } | 
 | 8011 |   } | 
 | 8012 |  | 
 | 8013 |   // Field constructors. | 
 | 8014 |   for (RecordDecl::field_iterator F = ClassDecl->field_begin(), | 
 | 8015 |                                FEnd = ClassDecl->field_end(); | 
 | 8016 |        F != FEnd; ++F) { | 
 | 8017 |     if (F->hasInClassInitializer()) { | 
 | 8018 |       if (Expr *E = F->getInClassInitializer()) | 
 | 8019 |         ExceptSpec.CalledExpr(E); | 
 | 8020 |       else if (!F->isInvalidDecl()) | 
 | 8021 |         Diag(CD->getLocation(), | 
 | 8022 |              diag::err_in_class_initializer_references_def_ctor) << CD; | 
 | 8023 |     } else if (const RecordType *RecordTy | 
 | 8024 |               = Context.getBaseElementType(F->getType())->getAs<RecordType>()) { | 
 | 8025 |       CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); | 
 | 8026 |       CXXConstructorDecl *Constructor = LookupDefaultConstructor(FieldRecDecl); | 
 | 8027 |       if (Constructor) | 
 | 8028 |         ExceptSpec.CalledDecl(F->getLocation(), Constructor); | 
 | 8029 |     } | 
 | 8030 |   } | 
 | 8031 |  | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 8032 |   return ExceptSpec; | 
 | 8033 | } | 
 | 8034 |  | 
| Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 8035 | namespace { | 
 | 8036 | /// RAII object to register a special member as being currently declared. | 
 | 8037 | struct DeclaringSpecialMember { | 
 | 8038 |   Sema &S; | 
 | 8039 |   Sema::SpecialMemberDecl D; | 
 | 8040 |   bool WasAlreadyBeingDeclared; | 
 | 8041 |  | 
 | 8042 |   DeclaringSpecialMember(Sema &S, CXXRecordDecl *RD, Sema::CXXSpecialMember CSM) | 
 | 8043 |     : S(S), D(RD, CSM) { | 
 | 8044 |     WasAlreadyBeingDeclared = !S.SpecialMembersBeingDeclared.insert(D); | 
 | 8045 |     if (WasAlreadyBeingDeclared) | 
 | 8046 |       // This almost never happens, but if it does, ensure that our cache | 
 | 8047 |       // doesn't contain a stale result. | 
 | 8048 |       S.SpecialMemberCache.clear(); | 
 | 8049 |  | 
 | 8050 |     // FIXME: Register a note to be produced if we encounter an error while | 
 | 8051 |     // declaring the special member. | 
 | 8052 |   } | 
 | 8053 |   ~DeclaringSpecialMember() { | 
 | 8054 |     if (!WasAlreadyBeingDeclared) | 
 | 8055 |       S.SpecialMembersBeingDeclared.erase(D); | 
 | 8056 |   } | 
 | 8057 |  | 
 | 8058 |   /// \brief Are we already trying to declare this special member? | 
 | 8059 |   bool isAlreadyBeingDeclared() const { | 
 | 8060 |     return WasAlreadyBeingDeclared; | 
 | 8061 |   } | 
 | 8062 | }; | 
 | 8063 | } | 
 | 8064 |  | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 8065 | CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( | 
 | 8066 |                                                      CXXRecordDecl *ClassDecl) { | 
 | 8067 |   // C++ [class.ctor]p5: | 
 | 8068 |   //   A default constructor for a class X is a constructor of class X | 
 | 8069 |   //   that can be called without an argument. If there is no | 
 | 8070 |   //   user-declared constructor for class X, a default constructor is | 
 | 8071 |   //   implicitly declared. An implicitly-declared default constructor | 
 | 8072 |   //   is an inline public member of its class. | 
| Richard Smith | d0adeb6 | 2012-11-27 21:20:31 +0000 | [diff] [blame] | 8073 |   assert(ClassDecl->needsImplicitDefaultConstructor() &&  | 
| Sean Hunt | 001cad9 | 2011-05-10 00:49:42 +0000 | [diff] [blame] | 8074 |          "Should not build implicit default constructor!"); | 
 | 8075 |  | 
| Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 8076 |   DeclaringSpecialMember DSM(*this, ClassDecl, CXXDefaultConstructor); | 
 | 8077 |   if (DSM.isAlreadyBeingDeclared()) | 
 | 8078 |     return 0; | 
 | 8079 |  | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 8080 |   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl, | 
 | 8081 |                                                      CXXDefaultConstructor, | 
 | 8082 |                                                      false); | 
 | 8083 |  | 
| Douglas Gregor | eb8c670 | 2010-07-01 22:31:05 +0000 | [diff] [blame] | 8084 |   // Create the actual constructor declaration. | 
| Douglas Gregor | 32df23e | 2010-07-01 22:02:46 +0000 | [diff] [blame] | 8085 |   CanQualType ClassType | 
 | 8086 |     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl)); | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 8087 |   SourceLocation ClassLoc = ClassDecl->getLocation(); | 
| Douglas Gregor | 32df23e | 2010-07-01 22:02:46 +0000 | [diff] [blame] | 8088 |   DeclarationName Name | 
 | 8089 |     = Context.DeclarationNames.getCXXConstructorName(ClassType); | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 8090 |   DeclarationNameInfo NameInfo(Name, ClassLoc); | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 8091 |   CXXConstructorDecl *DefaultCon = CXXConstructorDecl::Create( | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8092 |       Context, ClassDecl, ClassLoc, NameInfo, /*Type*/QualType(), /*TInfo=*/0, | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 8093 |       /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true, | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 8094 |       Constexpr); | 
| Douglas Gregor | 32df23e | 2010-07-01 22:02:46 +0000 | [diff] [blame] | 8095 |   DefaultCon->setAccess(AS_public); | 
| Sean Hunt | 1e23865 | 2011-05-12 03:51:51 +0000 | [diff] [blame] | 8096 |   DefaultCon->setDefaulted(); | 
| Douglas Gregor | 32df23e | 2010-07-01 22:02:46 +0000 | [diff] [blame] | 8097 |   DefaultCon->setImplicit(); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8098 |  | 
 | 8099 |   // Build an exception specification pointing back at this constructor. | 
| Reid Kleckner | ef07203 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 8100 |   FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, DefaultCon); | 
| Dmitri Gribenko | 5543169 | 2013-05-05 00:41:58 +0000 | [diff] [blame] | 8101 |   DefaultCon->setType(Context.getFunctionType(Context.VoidTy, None, EPI)); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8102 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 8103 |   // We don't need to use SpecialMemberIsTrivial here; triviality for default | 
 | 8104 |   // constructors is easy to compute. | 
 | 8105 |   DefaultCon->setTrivial(ClassDecl->hasTrivialDefaultConstructor()); | 
 | 8106 |  | 
 | 8107 |   if (ShouldDeleteSpecialMember(DefaultCon, CXXDefaultConstructor)) | 
| Richard Smith | 0ab5b4c | 2013-04-02 19:38:47 +0000 | [diff] [blame] | 8108 |     SetDeclDeleted(DefaultCon, ClassLoc); | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 8109 |  | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 8110 |   // Note that we have declared this constructor. | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 8111 |   ++ASTContext::NumImplicitDefaultConstructorsDeclared; | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 8112 |  | 
| Douglas Gregor | 23c94db | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 8113 |   if (Scope *S = getScopeForContext(ClassDecl)) | 
| Douglas Gregor | 1827403 | 2010-07-03 00:47:00 +0000 | [diff] [blame] | 8114 |     PushOnScopeChains(DefaultCon, S, false); | 
 | 8115 |   ClassDecl->addDecl(DefaultCon); | 
| Sean Hunt | 71a682f | 2011-05-18 03:41:58 +0000 | [diff] [blame] | 8116 |  | 
| Douglas Gregor | 32df23e | 2010-07-01 22:02:46 +0000 | [diff] [blame] | 8117 |   return DefaultCon; | 
 | 8118 | } | 
 | 8119 |  | 
| Fariborz Jahanian | f8dcb86 | 2009-06-19 19:55:27 +0000 | [diff] [blame] | 8120 | void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, | 
 | 8121 |                                             CXXConstructorDecl *Constructor) { | 
| Sean Hunt | 1e23865 | 2011-05-12 03:51:51 +0000 | [diff] [blame] | 8122 |   assert((Constructor->isDefaulted() && Constructor->isDefaultConstructor() && | 
| Sean Hunt | cd10dec | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 8123 |           !Constructor->doesThisDeclarationHaveABody() && | 
 | 8124 |           !Constructor->isDeleted()) && | 
| Fariborz Jahanian | 05a5c45 | 2009-06-22 20:37:23 +0000 | [diff] [blame] | 8125 |     "DefineImplicitDefaultConstructor - call it for implicit default ctor"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 8126 |  | 
| Anders Carlsson | f6513ed | 2010-04-23 16:04:08 +0000 | [diff] [blame] | 8127 |   CXXRecordDecl *ClassDecl = Constructor->getParent(); | 
| Eli Friedman | 80c30da | 2009-11-09 19:20:36 +0000 | [diff] [blame] | 8128 |   assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid constructor"); | 
| Eli Friedman | 49c16da | 2009-11-09 01:05:47 +0000 | [diff] [blame] | 8129 |  | 
| Eli Friedman | 9a14db3 | 2012-10-18 20:14:08 +0000 | [diff] [blame] | 8130 |   SynthesizedFunctionScope Scope(*this, Constructor); | 
| Argyrios Kyrtzidis | 9c4eb1f | 2010-11-19 00:19:12 +0000 | [diff] [blame] | 8131 |   DiagnosticErrorTrap Trap(Diags); | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 8132 |   if (SetCtorInitializers(Constructor, /*AnyErrors=*/false) || | 
| Douglas Gregor | c63d2c8 | 2010-05-12 16:39:35 +0000 | [diff] [blame] | 8133 |       Trap.hasErrorOccurred()) { | 
| Anders Carlsson | 3790980 | 2009-11-30 21:24:50 +0000 | [diff] [blame] | 8134 |     Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
| Sean Hunt | f961ea5 | 2011-05-10 19:08:14 +0000 | [diff] [blame] | 8135 |       << CXXDefaultConstructor << Context.getTagDeclType(ClassDecl); | 
| Eli Friedman | 80c30da | 2009-11-09 19:20:36 +0000 | [diff] [blame] | 8136 |     Constructor->setInvalidDecl(); | 
| Douglas Gregor | 4ada9d3 | 2010-09-20 16:48:21 +0000 | [diff] [blame] | 8137 |     return; | 
| Eli Friedman | 80c30da | 2009-11-09 19:20:36 +0000 | [diff] [blame] | 8138 |   } | 
| Douglas Gregor | 4ada9d3 | 2010-09-20 16:48:21 +0000 | [diff] [blame] | 8139 |  | 
 | 8140 |   SourceLocation Loc = Constructor->getLocation(); | 
| Benjamin Kramer | 3a2d0fb | 2012-07-04 17:03:41 +0000 | [diff] [blame] | 8141 |   Constructor->setBody(new (Context) CompoundStmt(Loc)); | 
| Douglas Gregor | 4ada9d3 | 2010-09-20 16:48:21 +0000 | [diff] [blame] | 8142 |  | 
| Eli Friedman | 86164e8 | 2013-09-05 00:02:25 +0000 | [diff] [blame] | 8143 |   Constructor->markUsed(Context); | 
| Douglas Gregor | 4ada9d3 | 2010-09-20 16:48:21 +0000 | [diff] [blame] | 8144 |   MarkVTableUsed(CurrentLocation, ClassDecl); | 
| Sebastian Redl | 58a2cd8 | 2011-04-24 16:28:06 +0000 | [diff] [blame] | 8145 |  | 
 | 8146 |   if (ASTMutationListener *L = getASTMutationListener()) { | 
 | 8147 |     L->CompletedImplicitDefinition(Constructor); | 
 | 8148 |   } | 
| Fariborz Jahanian | f8dcb86 | 2009-06-19 19:55:27 +0000 | [diff] [blame] | 8149 | } | 
 | 8150 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 8151 | void Sema::ActOnFinishDelayedMemberInitializers(Decl *D) { | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 8152 |   // Check that any explicitly-defaulted methods have exception specifications | 
 | 8153 |   // compatible with their implicit exception specifications. | 
 | 8154 |   CheckDelayedExplicitlyDefaultedMemberExceptionSpecs(); | 
| Richard Trieu | ef8f90c | 2013-09-20 03:03:06 +0000 | [diff] [blame] | 8155 |  | 
 | 8156 |   // Once all the member initializers are processed, perform checks to see if | 
 | 8157 |   // any unintialized use is happeneing. | 
 | 8158 |   if (getDiagnostics().getDiagnosticLevel(diag::warn_field_is_uninit, | 
 | 8159 |                                           D->getLocation()) | 
 | 8160 |       == DiagnosticsEngine::Ignored) | 
 | 8161 |     return; | 
 | 8162 |  | 
 | 8163 |   CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D); | 
 | 8164 |   if (!RD) return; | 
 | 8165 |  | 
 | 8166 |   // Holds fields that are uninitialized. | 
 | 8167 |   llvm::SmallPtrSet<ValueDecl*, 4> UninitializedFields; | 
 | 8168 |  | 
 | 8169 |   // In the beginning, every field is uninitialized. | 
 | 8170 |   for (DeclContext::decl_iterator I = RD->decls_begin(), E = RD->decls_end(); | 
 | 8171 |        I != E; ++I) { | 
 | 8172 |     if (FieldDecl *FD = dyn_cast<FieldDecl>(*I)) { | 
 | 8173 |       UninitializedFields.insert(FD); | 
 | 8174 |     } else if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(*I)) { | 
 | 8175 |       UninitializedFields.insert(IFD->getAnonField()); | 
 | 8176 |     } | 
 | 8177 |   } | 
 | 8178 |  | 
 | 8179 |   for (DeclContext::decl_iterator I = RD->decls_begin(), E = RD->decls_end(); | 
 | 8180 |        I != E; ++I) { | 
 | 8181 |     FieldDecl *FD = dyn_cast<FieldDecl>(*I); | 
 | 8182 |     if (!FD) | 
 | 8183 |       if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(*I)) | 
 | 8184 |         FD = IFD->getAnonField(); | 
 | 8185 |  | 
 | 8186 |     if (!FD) | 
 | 8187 |       continue; | 
 | 8188 |  | 
 | 8189 |     Expr *InitExpr = FD->getInClassInitializer(); | 
 | 8190 |     if (!InitExpr) { | 
 | 8191 |       // Uninitialized reference types will give an error. | 
 | 8192 |       // Record types with an initializer are default initialized. | 
 | 8193 |       QualType FieldType = FD->getType(); | 
 | 8194 |       if (FieldType->isReferenceType() || FieldType->isRecordType()) | 
 | 8195 |         UninitializedFields.erase(FD); | 
 | 8196 |       continue; | 
 | 8197 |     } | 
 | 8198 |  | 
 | 8199 |     CheckInitExprContainsUninitializedFields( | 
 | 8200 |         *this, InitExpr, FD, UninitializedFields, | 
 | 8201 |         UninitializedFields.count(FD)/*WarnOnSelfReference*/); | 
 | 8202 |  | 
 | 8203 |     UninitializedFields.erase(FD); | 
 | 8204 |   } | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 8205 | } | 
 | 8206 |  | 
| Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 8207 | namespace { | 
 | 8208 | /// Information on inheriting constructors to declare. | 
 | 8209 | class InheritingConstructorInfo { | 
 | 8210 | public: | 
 | 8211 |   InheritingConstructorInfo(Sema &SemaRef, CXXRecordDecl *Derived) | 
 | 8212 |       : SemaRef(SemaRef), Derived(Derived) { | 
 | 8213 |     // Mark the constructors that we already have in the derived class. | 
 | 8214 |     // | 
 | 8215 |     // C++11 [class.inhctor]p3: [...] a constructor is implicitly declared [...] | 
 | 8216 |     //   unless there is a user-declared constructor with the same signature in | 
 | 8217 |     //   the class where the using-declaration appears. | 
 | 8218 |     visitAll(Derived, &InheritingConstructorInfo::noteDeclaredInDerived); | 
 | 8219 |   } | 
 | 8220 |  | 
 | 8221 |   void inheritAll(CXXRecordDecl *RD) { | 
 | 8222 |     visitAll(RD, &InheritingConstructorInfo::inherit); | 
 | 8223 |   } | 
 | 8224 |  | 
 | 8225 | private: | 
 | 8226 |   /// Information about an inheriting constructor. | 
 | 8227 |   struct InheritingConstructor { | 
 | 8228 |     InheritingConstructor() | 
 | 8229 |       : DeclaredInDerived(false), BaseCtor(0), DerivedCtor(0) {} | 
 | 8230 |  | 
 | 8231 |     /// If \c true, a constructor with this signature is already declared | 
 | 8232 |     /// in the derived class. | 
 | 8233 |     bool DeclaredInDerived; | 
 | 8234 |  | 
 | 8235 |     /// The constructor which is inherited. | 
 | 8236 |     const CXXConstructorDecl *BaseCtor; | 
 | 8237 |  | 
 | 8238 |     /// The derived constructor we declared. | 
 | 8239 |     CXXConstructorDecl *DerivedCtor; | 
 | 8240 |   }; | 
 | 8241 |  | 
 | 8242 |   /// Inheriting constructors with a given canonical type. There can be at | 
 | 8243 |   /// most one such non-template constructor, and any number of templated | 
 | 8244 |   /// constructors. | 
 | 8245 |   struct InheritingConstructorsForType { | 
 | 8246 |     InheritingConstructor NonTemplate; | 
| Robert Wilhelm | e7205c0 | 2013-08-10 12:33:24 +0000 | [diff] [blame] | 8247 |     SmallVector<std::pair<TemplateParameterList *, InheritingConstructor>, 4> | 
 | 8248 |         Templates; | 
| Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 8249 |  | 
 | 8250 |     InheritingConstructor &getEntry(Sema &S, const CXXConstructorDecl *Ctor) { | 
 | 8251 |       if (FunctionTemplateDecl *FTD = Ctor->getDescribedFunctionTemplate()) { | 
 | 8252 |         TemplateParameterList *ParamList = FTD->getTemplateParameters(); | 
 | 8253 |         for (unsigned I = 0, N = Templates.size(); I != N; ++I) | 
 | 8254 |           if (S.TemplateParameterListsAreEqual(ParamList, Templates[I].first, | 
 | 8255 |                                                false, S.TPL_TemplateMatch)) | 
 | 8256 |             return Templates[I].second; | 
 | 8257 |         Templates.push_back(std::make_pair(ParamList, InheritingConstructor())); | 
 | 8258 |         return Templates.back().second; | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 8259 |       } | 
| Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 8260 |  | 
 | 8261 |       return NonTemplate; | 
 | 8262 |     } | 
 | 8263 |   }; | 
 | 8264 |  | 
 | 8265 |   /// Get or create the inheriting constructor record for a constructor. | 
 | 8266 |   InheritingConstructor &getEntry(const CXXConstructorDecl *Ctor, | 
 | 8267 |                                   QualType CtorType) { | 
 | 8268 |     return Map[CtorType.getCanonicalType()->castAs<FunctionProtoType>()] | 
 | 8269 |         .getEntry(SemaRef, Ctor); | 
 | 8270 |   } | 
 | 8271 |  | 
 | 8272 |   typedef void (InheritingConstructorInfo::*VisitFn)(const CXXConstructorDecl*); | 
 | 8273 |  | 
 | 8274 |   /// Process all constructors for a class. | 
 | 8275 |   void visitAll(const CXXRecordDecl *RD, VisitFn Callback) { | 
 | 8276 |     for (CXXRecordDecl::ctor_iterator CtorIt = RD->ctor_begin(), | 
 | 8277 |                                       CtorE = RD->ctor_end(); | 
 | 8278 |          CtorIt != CtorE; ++CtorIt) | 
 | 8279 |       (this->*Callback)(*CtorIt); | 
 | 8280 |     for (CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl> | 
 | 8281 |              I(RD->decls_begin()), E(RD->decls_end()); | 
 | 8282 |          I != E; ++I) { | 
 | 8283 |       const FunctionDecl *FD = (*I)->getTemplatedDecl(); | 
 | 8284 |       if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) | 
 | 8285 |         (this->*Callback)(CD); | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 8286 |     } | 
 | 8287 |   } | 
| Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 8288 |  | 
 | 8289 |   /// Note that a constructor (or constructor template) was declared in Derived. | 
 | 8290 |   void noteDeclaredInDerived(const CXXConstructorDecl *Ctor) { | 
 | 8291 |     getEntry(Ctor, Ctor->getType()).DeclaredInDerived = true; | 
 | 8292 |   } | 
 | 8293 |  | 
 | 8294 |   /// Inherit a single constructor. | 
 | 8295 |   void inherit(const CXXConstructorDecl *Ctor) { | 
 | 8296 |     const FunctionProtoType *CtorType = | 
 | 8297 |         Ctor->getType()->castAs<FunctionProtoType>(); | 
 | 8298 |     ArrayRef<QualType> ArgTypes(CtorType->getArgTypes()); | 
 | 8299 |     FunctionProtoType::ExtProtoInfo EPI = CtorType->getExtProtoInfo(); | 
 | 8300 |  | 
 | 8301 |     SourceLocation UsingLoc = getUsingLoc(Ctor->getParent()); | 
 | 8302 |  | 
 | 8303 |     // Core issue (no number yet): the ellipsis is always discarded. | 
 | 8304 |     if (EPI.Variadic) { | 
 | 8305 |       SemaRef.Diag(UsingLoc, diag::warn_using_decl_constructor_ellipsis); | 
 | 8306 |       SemaRef.Diag(Ctor->getLocation(), | 
 | 8307 |                    diag::note_using_decl_constructor_ellipsis); | 
 | 8308 |       EPI.Variadic = false; | 
 | 8309 |     } | 
 | 8310 |  | 
 | 8311 |     // Declare a constructor for each number of parameters. | 
 | 8312 |     // | 
 | 8313 |     // C++11 [class.inhctor]p1: | 
 | 8314 |     //   The candidate set of inherited constructors from the class X named in | 
 | 8315 |     //   the using-declaration consists of [... modulo defects ...] for each | 
 | 8316 |     //   constructor or constructor template of X, the set of constructors or | 
 | 8317 |     //   constructor templates that results from omitting any ellipsis parameter | 
 | 8318 |     //   specification and successively omitting parameters with a default | 
 | 8319 |     //   argument from the end of the parameter-type-list | 
| Richard Smith | 987c030 | 2013-04-17 19:00:52 +0000 | [diff] [blame] | 8320 |     unsigned MinParams = minParamsToInherit(Ctor); | 
 | 8321 |     unsigned Params = Ctor->getNumParams(); | 
 | 8322 |     if (Params >= MinParams) { | 
 | 8323 |       do | 
 | 8324 |         declareCtor(UsingLoc, Ctor, | 
 | 8325 |                     SemaRef.Context.getFunctionType( | 
 | 8326 |                         Ctor->getResultType(), ArgTypes.slice(0, Params), EPI)); | 
 | 8327 |       while (Params > MinParams && | 
 | 8328 |              Ctor->getParamDecl(--Params)->hasDefaultArg()); | 
 | 8329 |     } | 
| Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 8330 |   } | 
 | 8331 |  | 
 | 8332 |   /// Find the using-declaration which specified that we should inherit the | 
 | 8333 |   /// constructors of \p Base. | 
 | 8334 |   SourceLocation getUsingLoc(const CXXRecordDecl *Base) { | 
 | 8335 |     // No fancy lookup required; just look for the base constructor name | 
 | 8336 |     // directly within the derived class. | 
 | 8337 |     ASTContext &Context = SemaRef.Context; | 
 | 8338 |     DeclarationName Name = Context.DeclarationNames.getCXXConstructorName( | 
 | 8339 |         Context.getCanonicalType(Context.getRecordType(Base))); | 
 | 8340 |     DeclContext::lookup_const_result Decls = Derived->lookup(Name); | 
 | 8341 |     return Decls.empty() ? Derived->getLocation() : Decls[0]->getLocation(); | 
 | 8342 |   } | 
 | 8343 |  | 
 | 8344 |   unsigned minParamsToInherit(const CXXConstructorDecl *Ctor) { | 
 | 8345 |     // C++11 [class.inhctor]p3: | 
 | 8346 |     //   [F]or each constructor template in the candidate set of inherited | 
 | 8347 |     //   constructors, a constructor template is implicitly declared | 
 | 8348 |     if (Ctor->getDescribedFunctionTemplate()) | 
 | 8349 |       return 0; | 
 | 8350 |  | 
 | 8351 |     //   For each non-template constructor in the candidate set of inherited | 
 | 8352 |     //   constructors other than a constructor having no parameters or a | 
 | 8353 |     //   copy/move constructor having a single parameter, a constructor is | 
 | 8354 |     //   implicitly declared [...] | 
 | 8355 |     if (Ctor->getNumParams() == 0) | 
 | 8356 |       return 1; | 
 | 8357 |     if (Ctor->isCopyOrMoveConstructor()) | 
 | 8358 |       return 2; | 
 | 8359 |  | 
 | 8360 |     // Per discussion on core reflector, never inherit a constructor which | 
 | 8361 |     // would become a default, copy, or move constructor of Derived either. | 
 | 8362 |     const ParmVarDecl *PD = Ctor->getParamDecl(0); | 
 | 8363 |     const ReferenceType *RT = PD->getType()->getAs<ReferenceType>(); | 
 | 8364 |     return (RT && RT->getPointeeCXXRecordDecl() == Derived) ? 2 : 1; | 
 | 8365 |   } | 
 | 8366 |  | 
 | 8367 |   /// Declare a single inheriting constructor, inheriting the specified | 
 | 8368 |   /// constructor, with the given type. | 
 | 8369 |   void declareCtor(SourceLocation UsingLoc, const CXXConstructorDecl *BaseCtor, | 
 | 8370 |                    QualType DerivedType) { | 
 | 8371 |     InheritingConstructor &Entry = getEntry(BaseCtor, DerivedType); | 
 | 8372 |  | 
 | 8373 |     // C++11 [class.inhctor]p3: | 
 | 8374 |     //   ... a constructor is implicitly declared with the same constructor | 
 | 8375 |     //   characteristics unless there is a user-declared constructor with | 
 | 8376 |     //   the same signature in the class where the using-declaration appears | 
 | 8377 |     if (Entry.DeclaredInDerived) | 
 | 8378 |       return; | 
 | 8379 |  | 
 | 8380 |     // C++11 [class.inhctor]p7: | 
 | 8381 |     //   If two using-declarations declare inheriting constructors with the | 
 | 8382 |     //   same signature, the program is ill-formed | 
 | 8383 |     if (Entry.DerivedCtor) { | 
 | 8384 |       if (BaseCtor->getParent() != Entry.BaseCtor->getParent()) { | 
 | 8385 |         // Only diagnose this once per constructor. | 
 | 8386 |         if (Entry.DerivedCtor->isInvalidDecl()) | 
 | 8387 |           return; | 
 | 8388 |         Entry.DerivedCtor->setInvalidDecl(); | 
 | 8389 |  | 
 | 8390 |         SemaRef.Diag(UsingLoc, diag::err_using_decl_constructor_conflict); | 
 | 8391 |         SemaRef.Diag(BaseCtor->getLocation(), | 
 | 8392 |                      diag::note_using_decl_constructor_conflict_current_ctor); | 
 | 8393 |         SemaRef.Diag(Entry.BaseCtor->getLocation(), | 
 | 8394 |                      diag::note_using_decl_constructor_conflict_previous_ctor); | 
 | 8395 |         SemaRef.Diag(Entry.DerivedCtor->getLocation(), | 
 | 8396 |                      diag::note_using_decl_constructor_conflict_previous_using); | 
 | 8397 |       } else { | 
 | 8398 |         // Core issue (no number): if the same inheriting constructor is | 
 | 8399 |         // produced by multiple base class constructors from the same base | 
 | 8400 |         // class, the inheriting constructor is defined as deleted. | 
 | 8401 |         SemaRef.SetDeclDeleted(Entry.DerivedCtor, UsingLoc); | 
 | 8402 |       } | 
 | 8403 |  | 
 | 8404 |       return; | 
 | 8405 |     } | 
 | 8406 |  | 
 | 8407 |     ASTContext &Context = SemaRef.Context; | 
 | 8408 |     DeclarationName Name = Context.DeclarationNames.getCXXConstructorName( | 
 | 8409 |         Context.getCanonicalType(Context.getRecordType(Derived))); | 
 | 8410 |     DeclarationNameInfo NameInfo(Name, UsingLoc); | 
 | 8411 |  | 
 | 8412 |     TemplateParameterList *TemplateParams = 0; | 
 | 8413 |     if (const FunctionTemplateDecl *FTD = | 
 | 8414 |             BaseCtor->getDescribedFunctionTemplate()) { | 
 | 8415 |       TemplateParams = FTD->getTemplateParameters(); | 
 | 8416 |       // We're reusing template parameters from a different DeclContext. This | 
 | 8417 |       // is questionable at best, but works out because the template depth in | 
 | 8418 |       // both places is guaranteed to be 0. | 
 | 8419 |       // FIXME: Rebuild the template parameters in the new context, and | 
 | 8420 |       // transform the function type to refer to them. | 
 | 8421 |     } | 
 | 8422 |  | 
 | 8423 |     // Build type source info pointing at the using-declaration. This is | 
 | 8424 |     // required by template instantiation. | 
 | 8425 |     TypeSourceInfo *TInfo = | 
 | 8426 |         Context.getTrivialTypeSourceInfo(DerivedType, UsingLoc); | 
 | 8427 |     FunctionProtoTypeLoc ProtoLoc = | 
 | 8428 |         TInfo->getTypeLoc().IgnoreParens().castAs<FunctionProtoTypeLoc>(); | 
 | 8429 |  | 
 | 8430 |     CXXConstructorDecl *DerivedCtor = CXXConstructorDecl::Create( | 
 | 8431 |         Context, Derived, UsingLoc, NameInfo, DerivedType, | 
 | 8432 |         TInfo, BaseCtor->isExplicit(), /*Inline=*/true, | 
 | 8433 |         /*ImplicitlyDeclared=*/true, /*Constexpr=*/BaseCtor->isConstexpr()); | 
 | 8434 |  | 
 | 8435 |     // Build an unevaluated exception specification for this constructor. | 
 | 8436 |     const FunctionProtoType *FPT = DerivedType->castAs<FunctionProtoType>(); | 
 | 8437 |     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); | 
 | 8438 |     EPI.ExceptionSpecType = EST_Unevaluated; | 
 | 8439 |     EPI.ExceptionSpecDecl = DerivedCtor; | 
 | 8440 |     DerivedCtor->setType(Context.getFunctionType(FPT->getResultType(), | 
 | 8441 |                                                  FPT->getArgTypes(), EPI)); | 
 | 8442 |  | 
 | 8443 |     // Build the parameter declarations. | 
 | 8444 |     SmallVector<ParmVarDecl *, 16> ParamDecls; | 
 | 8445 |     for (unsigned I = 0, N = FPT->getNumArgs(); I != N; ++I) { | 
 | 8446 |       TypeSourceInfo *TInfo = | 
 | 8447 |           Context.getTrivialTypeSourceInfo(FPT->getArgType(I), UsingLoc); | 
 | 8448 |       ParmVarDecl *PD = ParmVarDecl::Create( | 
 | 8449 |           Context, DerivedCtor, UsingLoc, UsingLoc, /*IdentifierInfo=*/0, | 
 | 8450 |           FPT->getArgType(I), TInfo, SC_None, /*DefaultArg=*/0); | 
 | 8451 |       PD->setScopeInfo(0, I); | 
 | 8452 |       PD->setImplicit(); | 
 | 8453 |       ParamDecls.push_back(PD); | 
 | 8454 |       ProtoLoc.setArg(I, PD); | 
 | 8455 |     } | 
 | 8456 |  | 
 | 8457 |     // Set up the new constructor. | 
 | 8458 |     DerivedCtor->setAccess(BaseCtor->getAccess()); | 
 | 8459 |     DerivedCtor->setParams(ParamDecls); | 
 | 8460 |     DerivedCtor->setInheritedConstructor(BaseCtor); | 
 | 8461 |     if (BaseCtor->isDeleted()) | 
 | 8462 |       SemaRef.SetDeclDeleted(DerivedCtor, UsingLoc); | 
 | 8463 |  | 
 | 8464 |     // If this is a constructor template, build the template declaration. | 
 | 8465 |     if (TemplateParams) { | 
 | 8466 |       FunctionTemplateDecl *DerivedTemplate = | 
 | 8467 |           FunctionTemplateDecl::Create(SemaRef.Context, Derived, UsingLoc, Name, | 
 | 8468 |                                        TemplateParams, DerivedCtor); | 
 | 8469 |       DerivedTemplate->setAccess(BaseCtor->getAccess()); | 
 | 8470 |       DerivedCtor->setDescribedFunctionTemplate(DerivedTemplate); | 
 | 8471 |       Derived->addDecl(DerivedTemplate); | 
 | 8472 |     } else { | 
 | 8473 |       Derived->addDecl(DerivedCtor); | 
 | 8474 |     } | 
 | 8475 |  | 
 | 8476 |     Entry.BaseCtor = BaseCtor; | 
 | 8477 |     Entry.DerivedCtor = DerivedCtor; | 
 | 8478 |   } | 
 | 8479 |  | 
 | 8480 |   Sema &SemaRef; | 
 | 8481 |   CXXRecordDecl *Derived; | 
 | 8482 |   typedef llvm::DenseMap<const Type *, InheritingConstructorsForType> MapType; | 
 | 8483 |   MapType Map; | 
 | 8484 | }; | 
 | 8485 | } | 
 | 8486 |  | 
 | 8487 | void Sema::DeclareInheritingConstructors(CXXRecordDecl *ClassDecl) { | 
 | 8488 |   // Defer declaring the inheriting constructors until the class is | 
 | 8489 |   // instantiated. | 
 | 8490 |   if (ClassDecl->isDependentContext()) | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 8491 |     return; | 
 | 8492 |  | 
| Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 8493 |   // Find base classes from which we might inherit constructors. | 
 | 8494 |   SmallVector<CXXRecordDecl*, 4> InheritedBases; | 
 | 8495 |   for (CXXRecordDecl::base_class_iterator BaseIt = ClassDecl->bases_begin(), | 
 | 8496 |                                           BaseE = ClassDecl->bases_end(); | 
 | 8497 |        BaseIt != BaseE; ++BaseIt) | 
 | 8498 |     if (BaseIt->getInheritConstructors()) | 
 | 8499 |       InheritedBases.push_back(BaseIt->getType()->getAsCXXRecordDecl()); | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 8500 |  | 
| Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 8501 |   // Go no further if we're not inheriting any constructors. | 
 | 8502 |   if (InheritedBases.empty()) | 
 | 8503 |     return; | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 8504 |  | 
| Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 8505 |   // Declare the inherited constructors. | 
 | 8506 |   InheritingConstructorInfo ICI(*this, ClassDecl); | 
 | 8507 |   for (unsigned I = 0, N = InheritedBases.size(); I != N; ++I) | 
 | 8508 |     ICI.inheritAll(InheritedBases[I]); | 
| Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 8509 | } | 
 | 8510 |  | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 8511 | void Sema::DefineInheritingConstructor(SourceLocation CurrentLocation, | 
 | 8512 |                                        CXXConstructorDecl *Constructor) { | 
 | 8513 |   CXXRecordDecl *ClassDecl = Constructor->getParent(); | 
 | 8514 |   assert(Constructor->getInheritedConstructor() && | 
 | 8515 |          !Constructor->doesThisDeclarationHaveABody() && | 
 | 8516 |          !Constructor->isDeleted()); | 
 | 8517 |  | 
 | 8518 |   SynthesizedFunctionScope Scope(*this, Constructor); | 
 | 8519 |   DiagnosticErrorTrap Trap(Diags); | 
 | 8520 |   if (SetCtorInitializers(Constructor, /*AnyErrors=*/false) || | 
 | 8521 |       Trap.hasErrorOccurred()) { | 
 | 8522 |     Diag(CurrentLocation, diag::note_inhctor_synthesized_at) | 
 | 8523 |       << Context.getTagDeclType(ClassDecl); | 
 | 8524 |     Constructor->setInvalidDecl(); | 
 | 8525 |     return; | 
 | 8526 |   } | 
 | 8527 |  | 
 | 8528 |   SourceLocation Loc = Constructor->getLocation(); | 
 | 8529 |   Constructor->setBody(new (Context) CompoundStmt(Loc)); | 
 | 8530 |  | 
| Eli Friedman | 86164e8 | 2013-09-05 00:02:25 +0000 | [diff] [blame] | 8531 |   Constructor->markUsed(Context); | 
| Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 8532 |   MarkVTableUsed(CurrentLocation, ClassDecl); | 
 | 8533 |  | 
 | 8534 |   if (ASTMutationListener *L = getASTMutationListener()) { | 
 | 8535 |     L->CompletedImplicitDefinition(Constructor); | 
 | 8536 |   } | 
 | 8537 | } | 
 | 8538 |  | 
 | 8539 |  | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 8540 | Sema::ImplicitExceptionSpecification | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8541 | Sema::ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD) { | 
 | 8542 |   CXXRecordDecl *ClassDecl = MD->getParent(); | 
 | 8543 |  | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8544 |   // C++ [except.spec]p14:  | 
 | 8545 |   //   An implicitly declared special member function (Clause 12) shall have  | 
 | 8546 |   //   an exception-specification. | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 8547 |   ImplicitExceptionSpecification ExceptSpec(*this); | 
| Abramo Bagnara | cdb8076 | 2011-07-11 08:52:40 +0000 | [diff] [blame] | 8548 |   if (ClassDecl->isInvalidDecl()) | 
 | 8549 |     return ExceptSpec; | 
 | 8550 |  | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8551 |   // Direct base-class destructors. | 
 | 8552 |   for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(), | 
 | 8553 |                                        BEnd = ClassDecl->bases_end(); | 
 | 8554 |        B != BEnd; ++B) { | 
 | 8555 |     if (B->isVirtual()) // Handled below. | 
 | 8556 |       continue; | 
 | 8557 |      | 
 | 8558 |     if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 8559 |       ExceptSpec.CalledDecl(B->getLocStart(), | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8560 |                    LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl()))); | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8561 |   } | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8562 |  | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8563 |   // Virtual base-class destructors. | 
 | 8564 |   for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(), | 
 | 8565 |                                        BEnd = ClassDecl->vbases_end(); | 
 | 8566 |        B != BEnd; ++B) { | 
 | 8567 |     if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 8568 |       ExceptSpec.CalledDecl(B->getLocStart(), | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8569 |                   LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl()))); | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8570 |   } | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8571 |  | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8572 |   // Field destructors. | 
 | 8573 |   for (RecordDecl::field_iterator F = ClassDecl->field_begin(), | 
 | 8574 |                                FEnd = ClassDecl->field_end(); | 
 | 8575 |        F != FEnd; ++F) { | 
 | 8576 |     if (const RecordType *RecordTy | 
 | 8577 |         = Context.getBaseElementType(F->getType())->getAs<RecordType>()) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 8578 |       ExceptSpec.CalledDecl(F->getLocation(), | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8579 |                   LookupDestructor(cast<CXXRecordDecl>(RecordTy->getDecl()))); | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8580 |   } | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 8581 |  | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 8582 |   return ExceptSpec; | 
 | 8583 | } | 
 | 8584 |  | 
 | 8585 | CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) { | 
 | 8586 |   // C++ [class.dtor]p2: | 
 | 8587 |   //   If a class has no user-declared destructor, a destructor is | 
 | 8588 |   //   declared implicitly. An implicitly-declared destructor is an | 
 | 8589 |   //   inline public member of its class. | 
| Richard Smith | e5411b7 | 2012-12-01 02:35:44 +0000 | [diff] [blame] | 8590 |   assert(ClassDecl->needsImplicitDestructor()); | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 8591 |  | 
| Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 8592 |   DeclaringSpecialMember DSM(*this, ClassDecl, CXXDestructor); | 
 | 8593 |   if (DSM.isAlreadyBeingDeclared()) | 
 | 8594 |     return 0; | 
 | 8595 |  | 
| Douglas Gregor | 4923aa2 | 2010-07-02 20:37:36 +0000 | [diff] [blame] | 8596 |   // Create the actual destructor declaration. | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8597 |   CanQualType ClassType | 
 | 8598 |     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl)); | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 8599 |   SourceLocation ClassLoc = ClassDecl->getLocation(); | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8600 |   DeclarationName Name | 
 | 8601 |     = Context.DeclarationNames.getCXXDestructorName(ClassType); | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 8602 |   DeclarationNameInfo NameInfo(Name, ClassLoc); | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8603 |   CXXDestructorDecl *Destructor | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8604 |       = CXXDestructorDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, | 
 | 8605 |                                   QualType(), 0, /*isInline=*/true, | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 8606 |                                   /*isImplicitlyDeclared=*/true); | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8607 |   Destructor->setAccess(AS_public); | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 8608 |   Destructor->setDefaulted(); | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8609 |   Destructor->setImplicit(); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8610 |  | 
 | 8611 |   // Build an exception specification pointing back at this destructor. | 
| Reid Kleckner | ef07203 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 8612 |   FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, Destructor); | 
| Dmitri Gribenko | 5543169 | 2013-05-05 00:41:58 +0000 | [diff] [blame] | 8613 |   Destructor->setType(Context.getFunctionType(Context.VoidTy, None, EPI)); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8614 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 8615 |   AddOverriddenMethods(ClassDecl, Destructor); | 
 | 8616 |  | 
 | 8617 |   // We don't need to use SpecialMemberIsTrivial here; triviality for | 
 | 8618 |   // destructors is easy to compute. | 
 | 8619 |   Destructor->setTrivial(ClassDecl->hasTrivialDestructor()); | 
 | 8620 |  | 
 | 8621 |   if (ShouldDeleteSpecialMember(Destructor, CXXDestructor)) | 
| Richard Smith | 0ab5b4c | 2013-04-02 19:38:47 +0000 | [diff] [blame] | 8622 |     SetDeclDeleted(Destructor, ClassLoc); | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 8623 |  | 
| Douglas Gregor | 4923aa2 | 2010-07-02 20:37:36 +0000 | [diff] [blame] | 8624 |   // Note that we have declared this destructor. | 
| Douglas Gregor | 4923aa2 | 2010-07-02 20:37:36 +0000 | [diff] [blame] | 8625 |   ++ASTContext::NumImplicitDestructorsDeclared; | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8626 |  | 
| Douglas Gregor | 4923aa2 | 2010-07-02 20:37:36 +0000 | [diff] [blame] | 8627 |   // Introduce this destructor into its scope. | 
| Douglas Gregor | 23c94db | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 8628 |   if (Scope *S = getScopeForContext(ClassDecl)) | 
| Douglas Gregor | 4923aa2 | 2010-07-02 20:37:36 +0000 | [diff] [blame] | 8629 |     PushOnScopeChains(Destructor, S, false); | 
 | 8630 |   ClassDecl->addDecl(Destructor); | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 8631 |  | 
| Douglas Gregor | fabd43a | 2010-07-01 19:09:28 +0000 | [diff] [blame] | 8632 |   return Destructor; | 
 | 8633 | } | 
 | 8634 |  | 
| Fariborz Jahanian | 8d2b356 | 2009-06-26 23:49:16 +0000 | [diff] [blame] | 8635 | void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, | 
| Douglas Gregor | 4fe95f9 | 2009-09-04 19:04:08 +0000 | [diff] [blame] | 8636 |                                     CXXDestructorDecl *Destructor) { | 
| Sean Hunt | cd10dec | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 8637 |   assert((Destructor->isDefaulted() && | 
| Richard Smith | 03f6878 | 2012-02-26 07:51:39 +0000 | [diff] [blame] | 8638 |           !Destructor->doesThisDeclarationHaveABody() && | 
 | 8639 |           !Destructor->isDeleted()) && | 
| Fariborz Jahanian | 8d2b356 | 2009-06-26 23:49:16 +0000 | [diff] [blame] | 8640 |          "DefineImplicitDestructor - call it for implicit default dtor"); | 
| Anders Carlsson | 6d70139 | 2009-11-15 22:49:34 +0000 | [diff] [blame] | 8641 |   CXXRecordDecl *ClassDecl = Destructor->getParent(); | 
| Fariborz Jahanian | 8d2b356 | 2009-06-26 23:49:16 +0000 | [diff] [blame] | 8642 |   assert(ClassDecl && "DefineImplicitDestructor - invalid destructor"); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 8643 |  | 
| Douglas Gregor | c63d2c8 | 2010-05-12 16:39:35 +0000 | [diff] [blame] | 8644 |   if (Destructor->isInvalidDecl()) | 
 | 8645 |     return; | 
 | 8646 |  | 
| Eli Friedman | 9a14db3 | 2012-10-18 20:14:08 +0000 | [diff] [blame] | 8647 |   SynthesizedFunctionScope Scope(*this, Destructor); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 8648 |  | 
| Argyrios Kyrtzidis | 9c4eb1f | 2010-11-19 00:19:12 +0000 | [diff] [blame] | 8649 |   DiagnosticErrorTrap Trap(Diags); | 
| John McCall | ef027fe | 2010-03-16 21:39:52 +0000 | [diff] [blame] | 8650 |   MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(), | 
 | 8651 |                                          Destructor->getParent()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 8652 |  | 
| Douglas Gregor | c63d2c8 | 2010-05-12 16:39:35 +0000 | [diff] [blame] | 8653 |   if (CheckDestructor(Destructor) || Trap.hasErrorOccurred()) { | 
| Anders Carlsson | 3790980 | 2009-11-30 21:24:50 +0000 | [diff] [blame] | 8654 |     Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 8655 |       << CXXDestructor << Context.getTagDeclType(ClassDecl); | 
 | 8656 |  | 
 | 8657 |     Destructor->setInvalidDecl(); | 
 | 8658 |     return; | 
 | 8659 |   } | 
 | 8660 |  | 
| Douglas Gregor | 4ada9d3 | 2010-09-20 16:48:21 +0000 | [diff] [blame] | 8661 |   SourceLocation Loc = Destructor->getLocation(); | 
| Benjamin Kramer | 3a2d0fb | 2012-07-04 17:03:41 +0000 | [diff] [blame] | 8662 |   Destructor->setBody(new (Context) CompoundStmt(Loc)); | 
| Eli Friedman | 86164e8 | 2013-09-05 00:02:25 +0000 | [diff] [blame] | 8663 |   Destructor->markUsed(Context); | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 8664 |   MarkVTableUsed(CurrentLocation, ClassDecl); | 
| Sebastian Redl | 58a2cd8 | 2011-04-24 16:28:06 +0000 | [diff] [blame] | 8665 |  | 
 | 8666 |   if (ASTMutationListener *L = getASTMutationListener()) { | 
 | 8667 |     L->CompletedImplicitDefinition(Destructor); | 
 | 8668 |   } | 
| Fariborz Jahanian | 8d2b356 | 2009-06-26 23:49:16 +0000 | [diff] [blame] | 8669 | } | 
 | 8670 |  | 
| Richard Smith | a4156b8 | 2012-04-21 18:42:51 +0000 | [diff] [blame] | 8671 | /// \brief Perform any semantic analysis which needs to be delayed until all | 
 | 8672 | /// pending class member declarations have been parsed. | 
 | 8673 | void Sema::ActOnFinishCXXMemberDecls() { | 
| Douglas Gregor | 1031884 | 2013-02-01 04:49:10 +0000 | [diff] [blame] | 8674 |   // If the context is an invalid C++ class, just suppress these checks. | 
 | 8675 |   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(CurContext)) { | 
 | 8676 |     if (Record->isInvalidDecl()) { | 
 | 8677 |       DelayedDestructorExceptionSpecChecks.clear(); | 
 | 8678 |       return; | 
 | 8679 |     } | 
 | 8680 |   } | 
 | 8681 |  | 
| Richard Smith | a4156b8 | 2012-04-21 18:42:51 +0000 | [diff] [blame] | 8682 |   // Perform any deferred checking of exception specifications for virtual | 
 | 8683 |   // destructors. | 
 | 8684 |   for (unsigned i = 0, e = DelayedDestructorExceptionSpecChecks.size(); | 
 | 8685 |        i != e; ++i) { | 
 | 8686 |     const CXXDestructorDecl *Dtor = | 
 | 8687 |         DelayedDestructorExceptionSpecChecks[i].first; | 
 | 8688 |     assert(!Dtor->getParent()->isDependentType() && | 
 | 8689 |            "Should not ever add destructors of templates into the list."); | 
 | 8690 |     CheckOverridingFunctionExceptionSpec(Dtor, | 
 | 8691 |         DelayedDestructorExceptionSpecChecks[i].second); | 
 | 8692 |   } | 
 | 8693 |   DelayedDestructorExceptionSpecChecks.clear(); | 
 | 8694 | } | 
 | 8695 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8696 | void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, | 
 | 8697 |                                          CXXDestructorDecl *Destructor) { | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 8698 |   assert(getLangOpts().CPlusPlus11 && | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8699 |          "adjusting dtor exception specs was introduced in c++11"); | 
 | 8700 |  | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8701 |   // C++11 [class.dtor]p3: | 
 | 8702 |   //   A declaration of a destructor that does not have an exception- | 
 | 8703 |   //   specification is implicitly considered to have the same exception- | 
 | 8704 |   //   specification as an implicit declaration. | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8705 |   const FunctionProtoType *DtorType = Destructor->getType()-> | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8706 |                                         getAs<FunctionProtoType>(); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8707 |   if (DtorType->hasExceptionSpec()) | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8708 |     return; | 
 | 8709 |  | 
| Chandler Carruth | 3f224b2 | 2011-09-20 04:55:26 +0000 | [diff] [blame] | 8710 |   // Replace the destructor's type, building off the existing one. Fortunately, | 
 | 8711 |   // the only thing of interest in the destructor type is its extended info. | 
 | 8712 |   // The return and arguments are fixed. | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8713 |   FunctionProtoType::ExtProtoInfo EPI = DtorType->getExtProtoInfo(); | 
 | 8714 |   EPI.ExceptionSpecType = EST_Unevaluated; | 
 | 8715 |   EPI.ExceptionSpecDecl = Destructor; | 
| Dmitri Gribenko | 5543169 | 2013-05-05 00:41:58 +0000 | [diff] [blame] | 8716 |   Destructor->setType(Context.getFunctionType(Context.VoidTy, None, EPI)); | 
| Richard Smith | a4156b8 | 2012-04-21 18:42:51 +0000 | [diff] [blame] | 8717 |  | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8718 |   // FIXME: If the destructor has a body that could throw, and the newly created | 
 | 8719 |   // spec doesn't allow exceptions, we should emit a warning, because this | 
 | 8720 |   // change in behavior can break conforming C++03 programs at runtime. | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 8721 |   // However, we don't have a body or an exception specification yet, so it | 
 | 8722 |   // needs to be done somewhere else. | 
| Sebastian Redl | 0ee3391 | 2011-05-19 05:13:44 +0000 | [diff] [blame] | 8723 | } | 
 | 8724 |  | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 8725 | namespace { | 
 | 8726 | /// \brief An abstract base class for all helper classes used in building the | 
 | 8727 | //  copy/move operators. These classes serve as factory functions and help us | 
 | 8728 | //  avoid using the same Expr* in the AST twice. | 
 | 8729 | class ExprBuilder { | 
 | 8730 |   ExprBuilder(const ExprBuilder&) LLVM_DELETED_FUNCTION; | 
 | 8731 |   ExprBuilder &operator=(const ExprBuilder&) LLVM_DELETED_FUNCTION; | 
 | 8732 |  | 
 | 8733 | protected: | 
 | 8734 |   static Expr *assertNotNull(Expr *E) { | 
 | 8735 |     assert(E && "Expression construction must not fail."); | 
 | 8736 |     return E; | 
 | 8737 |   } | 
 | 8738 |  | 
 | 8739 | public: | 
 | 8740 |   ExprBuilder() {} | 
 | 8741 |   virtual ~ExprBuilder() {} | 
 | 8742 |  | 
 | 8743 |   virtual Expr *build(Sema &S, SourceLocation Loc) const = 0; | 
 | 8744 | }; | 
 | 8745 |  | 
 | 8746 | class RefBuilder: public ExprBuilder { | 
 | 8747 |   VarDecl *Var; | 
 | 8748 |   QualType VarType; | 
 | 8749 |  | 
 | 8750 | public: | 
 | 8751 |   virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE { | 
 | 8752 |     return assertNotNull(S.BuildDeclRefExpr(Var, VarType, VK_LValue, Loc).take()); | 
 | 8753 |   } | 
 | 8754 |  | 
 | 8755 |   RefBuilder(VarDecl *Var, QualType VarType) | 
 | 8756 |       : Var(Var), VarType(VarType) {} | 
 | 8757 | }; | 
 | 8758 |  | 
 | 8759 | class ThisBuilder: public ExprBuilder { | 
 | 8760 | public: | 
 | 8761 |   virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE { | 
 | 8762 |     return assertNotNull(S.ActOnCXXThis(Loc).takeAs<Expr>()); | 
 | 8763 |   } | 
 | 8764 | }; | 
 | 8765 |  | 
 | 8766 | class CastBuilder: public ExprBuilder { | 
 | 8767 |   const ExprBuilder &Builder; | 
 | 8768 |   QualType Type; | 
 | 8769 |   ExprValueKind Kind; | 
 | 8770 |   const CXXCastPath &Path; | 
 | 8771 |  | 
 | 8772 | public: | 
 | 8773 |   virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE { | 
 | 8774 |     return assertNotNull(S.ImpCastExprToType(Builder.build(S, Loc), Type, | 
 | 8775 |                                              CK_UncheckedDerivedToBase, Kind, | 
 | 8776 |                                              &Path).take()); | 
 | 8777 |   } | 
 | 8778 |  | 
 | 8779 |   CastBuilder(const ExprBuilder &Builder, QualType Type, ExprValueKind Kind, | 
 | 8780 |               const CXXCastPath &Path) | 
 | 8781 |       : Builder(Builder), Type(Type), Kind(Kind), Path(Path) {} | 
 | 8782 | }; | 
 | 8783 |  | 
 | 8784 | class DerefBuilder: public ExprBuilder { | 
 | 8785 |   const ExprBuilder &Builder; | 
 | 8786 |  | 
 | 8787 | public: | 
 | 8788 |   virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE { | 
 | 8789 |     return assertNotNull( | 
 | 8790 |         S.CreateBuiltinUnaryOp(Loc, UO_Deref, Builder.build(S, Loc)).take()); | 
 | 8791 |   } | 
 | 8792 |  | 
 | 8793 |   DerefBuilder(const ExprBuilder &Builder) : Builder(Builder) {} | 
 | 8794 | }; | 
 | 8795 |  | 
 | 8796 | class MemberBuilder: public ExprBuilder { | 
 | 8797 |   const ExprBuilder &Builder; | 
 | 8798 |   QualType Type; | 
 | 8799 |   CXXScopeSpec SS; | 
 | 8800 |   bool IsArrow; | 
 | 8801 |   LookupResult &MemberLookup; | 
 | 8802 |  | 
 | 8803 | public: | 
 | 8804 |   virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE { | 
 | 8805 |     return assertNotNull(S.BuildMemberReferenceExpr( | 
 | 8806 |         Builder.build(S, Loc), Type, Loc, IsArrow, SS, SourceLocation(), 0, | 
 | 8807 |         MemberLookup, 0).take()); | 
 | 8808 |   } | 
 | 8809 |  | 
 | 8810 |   MemberBuilder(const ExprBuilder &Builder, QualType Type, bool IsArrow, | 
 | 8811 |                 LookupResult &MemberLookup) | 
 | 8812 |       : Builder(Builder), Type(Type), IsArrow(IsArrow), | 
 | 8813 |         MemberLookup(MemberLookup) {} | 
 | 8814 | }; | 
 | 8815 |  | 
 | 8816 | class MoveCastBuilder: public ExprBuilder { | 
 | 8817 |   const ExprBuilder &Builder; | 
 | 8818 |  | 
 | 8819 | public: | 
 | 8820 |   virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE { | 
 | 8821 |     return assertNotNull(CastForMoving(S, Builder.build(S, Loc))); | 
 | 8822 |   } | 
 | 8823 |  | 
 | 8824 |   MoveCastBuilder(const ExprBuilder &Builder) : Builder(Builder) {} | 
 | 8825 | }; | 
 | 8826 |  | 
 | 8827 | class LvalueConvBuilder: public ExprBuilder { | 
 | 8828 |   const ExprBuilder &Builder; | 
 | 8829 |  | 
 | 8830 | public: | 
 | 8831 |   virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE { | 
 | 8832 |     return assertNotNull( | 
 | 8833 |         S.DefaultLvalueConversion(Builder.build(S, Loc)).take()); | 
 | 8834 |   } | 
 | 8835 |  | 
 | 8836 |   LvalueConvBuilder(const ExprBuilder &Builder) : Builder(Builder) {} | 
 | 8837 | }; | 
 | 8838 |  | 
 | 8839 | class SubscriptBuilder: public ExprBuilder { | 
 | 8840 |   const ExprBuilder &Base; | 
 | 8841 |   const ExprBuilder &Index; | 
 | 8842 |  | 
 | 8843 | public: | 
 | 8844 |   virtual Expr *build(Sema &S, SourceLocation Loc) const | 
 | 8845 |       LLVM_OVERRIDE { | 
 | 8846 |     return assertNotNull(S.CreateBuiltinArraySubscriptExpr( | 
 | 8847 |         Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).take()); | 
 | 8848 |   } | 
 | 8849 |  | 
 | 8850 |   SubscriptBuilder(const ExprBuilder &Base, const ExprBuilder &Index) | 
 | 8851 |       : Base(Base), Index(Index) {} | 
 | 8852 | }; | 
 | 8853 |  | 
 | 8854 | } // end anonymous namespace | 
 | 8855 |  | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 8856 | /// When generating a defaulted copy or move assignment operator, if a field | 
 | 8857 | /// should be copied with __builtin_memcpy rather than via explicit assignments, | 
 | 8858 | /// do so. This optimization only applies for arrays of scalars, and for arrays | 
 | 8859 | /// of class type where the selected copy/move-assignment operator is trivial. | 
 | 8860 | static StmtResult | 
 | 8861 | buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T, | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 8862 |                            const ExprBuilder &ToB, const ExprBuilder &FromB) { | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 8863 |   // Compute the size of the memory buffer to be copied. | 
 | 8864 |   QualType SizeType = S.Context.getSizeType(); | 
 | 8865 |   llvm::APInt Size(S.Context.getTypeSize(SizeType), | 
 | 8866 |                    S.Context.getTypeSizeInChars(T).getQuantity()); | 
 | 8867 |  | 
 | 8868 |   // Take the address of the field references for "from" and "to". We | 
 | 8869 |   // directly construct UnaryOperators here because semantic analysis | 
 | 8870 |   // does not permit us to take the address of an xvalue. | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 8871 |   Expr *From = FromB.build(S, Loc); | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 8872 |   From = new (S.Context) UnaryOperator(From, UO_AddrOf, | 
 | 8873 |                          S.Context.getPointerType(From->getType()), | 
 | 8874 |                          VK_RValue, OK_Ordinary, Loc); | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 8875 |   Expr *To = ToB.build(S, Loc); | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 8876 |   To = new (S.Context) UnaryOperator(To, UO_AddrOf, | 
 | 8877 |                        S.Context.getPointerType(To->getType()), | 
 | 8878 |                        VK_RValue, OK_Ordinary, Loc); | 
 | 8879 |  | 
 | 8880 |   const Type *E = T->getBaseElementTypeUnsafe(); | 
 | 8881 |   bool NeedsCollectableMemCpy = | 
 | 8882 |     E->isRecordType() && E->getAs<RecordType>()->getDecl()->hasObjectMember(); | 
 | 8883 |  | 
 | 8884 |   // Create a reference to the __builtin_objc_memmove_collectable function | 
 | 8885 |   StringRef MemCpyName = NeedsCollectableMemCpy ? | 
 | 8886 |     "__builtin_objc_memmove_collectable" : | 
 | 8887 |     "__builtin_memcpy"; | 
 | 8888 |   LookupResult R(S, &S.Context.Idents.get(MemCpyName), Loc, | 
 | 8889 |                  Sema::LookupOrdinaryName); | 
 | 8890 |   S.LookupName(R, S.TUScope, true); | 
 | 8891 |  | 
 | 8892 |   FunctionDecl *MemCpy = R.getAsSingle<FunctionDecl>(); | 
 | 8893 |   if (!MemCpy) | 
 | 8894 |     // Something went horribly wrong earlier, and we will have complained | 
 | 8895 |     // about it. | 
 | 8896 |     return StmtError(); | 
 | 8897 |  | 
 | 8898 |   ExprResult MemCpyRef = S.BuildDeclRefExpr(MemCpy, S.Context.BuiltinFnTy, | 
 | 8899 |                                             VK_RValue, Loc, 0); | 
 | 8900 |   assert(MemCpyRef.isUsable() && "Builtin reference cannot fail"); | 
 | 8901 |  | 
 | 8902 |   Expr *CallArgs[] = { | 
 | 8903 |     To, From, IntegerLiteral::Create(S.Context, Size, SizeType, Loc) | 
 | 8904 |   }; | 
 | 8905 |   ExprResult Call = S.ActOnCallExpr(/*Scope=*/0, MemCpyRef.take(), | 
 | 8906 |                                     Loc, CallArgs, Loc); | 
 | 8907 |  | 
 | 8908 |   assert(!Call.isInvalid() && "Call to __builtin_memcpy cannot fail!"); | 
 | 8909 |   return S.Owned(Call.takeAs<Stmt>()); | 
 | 8910 | } | 
 | 8911 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8912 | /// \brief Builds a statement that copies/moves the given entity from \p From to | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8913 | /// \c To. | 
 | 8914 | /// | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8915 | /// This routine is used to copy/move the members of a class with an | 
 | 8916 | /// implicitly-declared copy/move assignment operator. When the entities being | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8917 | /// copied are arrays, this routine builds for loops to copy them. | 
 | 8918 | /// | 
 | 8919 | /// \param S The Sema object used for type-checking. | 
 | 8920 | /// | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8921 | /// \param Loc The location where the implicit copy/move is being generated. | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8922 | /// | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8923 | /// \param T The type of the expressions being copied/moved. Both expressions | 
 | 8924 | /// must have this type. | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8925 | /// | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8926 | /// \param To The expression we are copying/moving to. | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8927 | /// | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8928 | /// \param From The expression we are copying/moving from. | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8929 | /// | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8930 | /// \param CopyingBaseSubobject Whether we're copying/moving a base subobject. | 
| Douglas Gregor | 6cdc161 | 2010-05-04 15:20:55 +0000 | [diff] [blame] | 8931 | /// Otherwise, it's a non-static member subobject. | 
 | 8932 | /// | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8933 | /// \param Copying Whether we're copying or moving. | 
 | 8934 | /// | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8935 | /// \param Depth Internal parameter recording the depth of the recursion. | 
 | 8936 | /// | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 8937 | /// \returns A statement or a loop that copies the expressions, or StmtResult(0) | 
 | 8938 | /// if a memcpy should be used instead. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 8939 | static StmtResult | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 8940 | buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T, | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 8941 |                                  const ExprBuilder &To, const ExprBuilder &From, | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 8942 |                                  bool CopyingBaseSubobject, bool Copying, | 
 | 8943 |                                  unsigned Depth = 0) { | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 8944 |   // C++11 [class.copy]p28: | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8945 |   //   Each subobject is assigned in the manner appropriate to its type: | 
 | 8946 |   // | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8947 |   //     - if the subobject is of class type, as if by a call to operator= with | 
 | 8948 |   //       the subobject as the object expression and the corresponding | 
 | 8949 |   //       subobject of x as a single function argument (as if by explicit | 
 | 8950 |   //       qualification; that is, ignoring any possible virtual overriding | 
 | 8951 |   //       functions in more derived classes); | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 8952 |   // | 
 | 8953 |   // C++03 [class.copy]p13: | 
 | 8954 |   //     - if the subobject is of class type, the copy assignment operator for | 
 | 8955 |   //       the class is used (as if by explicit qualification; that is, | 
 | 8956 |   //       ignoring any possible virtual overriding functions in more derived | 
 | 8957 |   //       classes); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8958 |   if (const RecordType *RecordTy = T->getAs<RecordType>()) { | 
 | 8959 |     CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 8960 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 8961 |     // Look for operator=. | 
 | 8962 |     DeclarationName Name | 
 | 8963 |       = S.Context.DeclarationNames.getCXXOperatorName(OO_Equal); | 
 | 8964 |     LookupResult OpLookup(S, Name, Loc, Sema::LookupOrdinaryName); | 
 | 8965 |     S.LookupQualifiedName(OpLookup, ClassDecl, false); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 8966 |  | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 8967 |     // Prior to C++11, filter out any result that isn't a copy/move-assignment | 
 | 8968 |     // operator. | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 8969 |     if (!S.getLangOpts().CPlusPlus11) { | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 8970 |       LookupResult::Filter F = OpLookup.makeFilter(); | 
 | 8971 |       while (F.hasNext()) { | 
 | 8972 |         NamedDecl *D = F.next(); | 
 | 8973 |         if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) | 
 | 8974 |           if (Method->isCopyAssignmentOperator() || | 
 | 8975 |               (!Copying && Method->isMoveAssignmentOperator())) | 
 | 8976 |             continue; | 
 | 8977 |  | 
 | 8978 |         F.erase(); | 
 | 8979 |       } | 
 | 8980 |       F.done(); | 
| John McCall | b020748 | 2010-03-16 06:11:48 +0000 | [diff] [blame] | 8981 |     } | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 8982 |  | 
| Douglas Gregor | 6cdc161 | 2010-05-04 15:20:55 +0000 | [diff] [blame] | 8983 |     // Suppress the protected check (C++ [class.protected]) for each of the | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 8984 |     // assignment operators we found. This strange dance is required when | 
| Douglas Gregor | 6cdc161 | 2010-05-04 15:20:55 +0000 | [diff] [blame] | 8985 |     // we're assigning via a base classes's copy-assignment operator. To | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 8986 |     // ensure that we're getting the right base class subobject (without | 
| Douglas Gregor | 6cdc161 | 2010-05-04 15:20:55 +0000 | [diff] [blame] | 8987 |     // ambiguities), we need to cast "this" to that subobject type; to | 
 | 8988 |     // ensure that we don't go through the virtual call mechanism, we need | 
 | 8989 |     // to qualify the operator= name with the base class (see below). However, | 
 | 8990 |     // this means that if the base class has a protected copy assignment | 
 | 8991 |     // operator, the protected member access check will fail. So, we | 
 | 8992 |     // rewrite "protected" access to "public" access in this case, since we | 
 | 8993 |     // know by construction that we're calling from a derived class. | 
 | 8994 |     if (CopyingBaseSubobject) { | 
 | 8995 |       for (LookupResult::iterator L = OpLookup.begin(), LEnd = OpLookup.end(); | 
 | 8996 |            L != LEnd; ++L) { | 
 | 8997 |         if (L.getAccess() == AS_protected) | 
 | 8998 |           L.setAccess(AS_public); | 
 | 8999 |       } | 
 | 9000 |     } | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9001 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9002 |     // Create the nested-name-specifier that will be used to qualify the | 
 | 9003 |     // reference to operator=; this is required to suppress the virtual | 
 | 9004 |     // call mechanism. | 
 | 9005 |     CXXScopeSpec SS; | 
| Manuel Klimek | 5b6a3dd | 2012-02-06 21:51:39 +0000 | [diff] [blame] | 9006 |     const Type *CanonicalT = S.Context.getCanonicalType(T.getTypePtr()); | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9007 |     SS.MakeTrivial(S.Context, | 
 | 9008 |                    NestedNameSpecifier::Create(S.Context, 0, false, | 
| Manuel Klimek | 5b6a3dd | 2012-02-06 21:51:39 +0000 | [diff] [blame] | 9009 |                                                CanonicalT), | 
| Douglas Gregor | c34348a | 2011-02-24 17:54:50 +0000 | [diff] [blame] | 9010 |                    Loc); | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9011 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9012 |     // Create the reference to operator=. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 9013 |     ExprResult OpEqualRef | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9014 |       = S.BuildMemberReferenceExpr(To.build(S, Loc), T, Loc, /*isArrow=*/false, | 
 | 9015 |                                    SS, /*TemplateKWLoc=*/SourceLocation(), | 
| Abramo Bagnara | e4b9276 | 2012-01-27 09:46:47 +0000 | [diff] [blame] | 9016 |                                    /*FirstQualifierInScope=*/0, | 
 | 9017 |                                    OpLookup, | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9018 |                                    /*TemplateArgs=*/0, | 
 | 9019 |                                    /*SuppressQualifierCheck=*/true); | 
 | 9020 |     if (OpEqualRef.isInvalid()) | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 9021 |       return StmtError(); | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9022 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9023 |     // Build the call to the assignment operator. | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 9024 |  | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9025 |     Expr *FromInst = From.build(S, Loc); | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9026 |     ExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/0, | 
| Douglas Gregor | a1a0478 | 2010-09-09 16:33:13 +0000 | [diff] [blame] | 9027 |                                                   OpEqualRef.takeAs<Expr>(), | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9028 |                                                   Loc, FromInst, Loc); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9029 |     if (Call.isInvalid()) | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 9030 |       return StmtError(); | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9031 |  | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9032 |     // If we built a call to a trivial 'operator=' while copying an array, | 
 | 9033 |     // bail out. We'll replace the whole shebang with a memcpy. | 
 | 9034 |     CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(Call.get()); | 
 | 9035 |     if (CE && CE->getMethodDecl()->isTrivial() && Depth) | 
 | 9036 |       return StmtResult((Stmt*)0); | 
 | 9037 |  | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9038 |     // Convert to an expression-statement, and clean up any produced | 
 | 9039 |     // temporaries. | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 9040 |     return S.ActOnExprStmt(Call); | 
| Fariborz Jahanian | c75bc2d | 2009-06-25 21:45:19 +0000 | [diff] [blame] | 9041 |   } | 
| John McCall | b020748 | 2010-03-16 06:11:48 +0000 | [diff] [blame] | 9042 |  | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9043 |   //     - if the subobject is of scalar type, the built-in assignment | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9044 |   //       operator is used. | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9045 |   const ConstantArrayType *ArrayTy = S.Context.getAsConstantArrayType(T); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9046 |   if (!ArrayTy) { | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9047 |     ExprResult Assignment = S.CreateBuiltinBinOp( | 
 | 9048 |         Loc, BO_Assign, To.build(S, Loc), From.build(S, Loc)); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9049 |     if (Assignment.isInvalid()) | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 9050 |       return StmtError(); | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 9051 |     return S.ActOnExprStmt(Assignment); | 
| Fariborz Jahanian | c75bc2d | 2009-06-25 21:45:19 +0000 | [diff] [blame] | 9052 |   } | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9053 |  | 
 | 9054 |   //     - if the subobject is an array, each element is assigned, in the | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9055 |   //       manner appropriate to the element type; | 
| Richard Smith | 044c8aa | 2012-11-13 00:54:12 +0000 | [diff] [blame] | 9056 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9057 |   // Construct a loop over the array bounds, e.g., | 
 | 9058 |   // | 
 | 9059 |   //   for (__SIZE_TYPE__ i0 = 0; i0 != array-size; ++i0) | 
 | 9060 |   // | 
 | 9061 |   // that will copy each of the array elements.  | 
 | 9062 |   QualType SizeType = S.Context.getSizeType(); | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9063 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9064 |   // Create the iteration variable. | 
 | 9065 |   IdentifierInfo *IterationVarName = 0; | 
 | 9066 |   { | 
| Dylan Noblesmith | f7ccbad | 2012-02-05 02:13:05 +0000 | [diff] [blame] | 9067 |     SmallString<8> Str; | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9068 |     llvm::raw_svector_ostream OS(Str); | 
 | 9069 |     OS << "__i" << Depth; | 
 | 9070 |     IterationVarName = &S.Context.Idents.get(OS.str()); | 
 | 9071 |   } | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 9072 |   VarDecl *IterationVar = VarDecl::Create(S.Context, S.CurContext, Loc, Loc, | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9073 |                                           IterationVarName, SizeType, | 
 | 9074 |                             S.Context.getTrivialTypeSourceInfo(SizeType, Loc), | 
| Rafael Espindola | d2615cc | 2013-04-03 19:27:57 +0000 | [diff] [blame] | 9075 |                                           SC_None); | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9076 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9077 |   // Initialize the iteration variable to zero. | 
 | 9078 |   llvm::APInt Zero(S.Context.getTypeSize(SizeType), 0); | 
| Argyrios Kyrtzidis | 9996a7f | 2010-08-28 09:06:06 +0000 | [diff] [blame] | 9079 |   IterationVar->setInit(IntegerLiteral::Create(S.Context, Zero, SizeType, Loc)); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9080 |  | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9081 |   // Creates a reference to the iteration variable. | 
 | 9082 |   RefBuilder IterationVarRef(IterationVar, SizeType); | 
 | 9083 |   LvalueConvBuilder IterationVarRefRVal(IterationVarRef); | 
| Eli Friedman | 8c38206 | 2012-01-23 02:35:22 +0000 | [diff] [blame] | 9084 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9085 |   // Create the DeclStmt that holds the iteration variable. | 
 | 9086 |   Stmt *InitStmt = new (S.Context) DeclStmt(DeclGroupRef(IterationVar),Loc,Loc); | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9087 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9088 |   // Subscript the "from" and "to" expressions with the iteration variable. | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9089 |   SubscriptBuilder FromIndexCopy(From, IterationVarRefRVal); | 
 | 9090 |   MoveCastBuilder FromIndexMove(FromIndexCopy); | 
 | 9091 |   const ExprBuilder *FromIndex; | 
 | 9092 |   if (Copying) | 
 | 9093 |     FromIndex = &FromIndexCopy; | 
 | 9094 |   else | 
 | 9095 |     FromIndex = &FromIndexMove; | 
 | 9096 |  | 
 | 9097 |   SubscriptBuilder ToIndex(To, IterationVarRefRVal); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9098 |  | 
 | 9099 |   // Build the copy/move for an individual element of the array. | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9100 |   StmtResult Copy = | 
 | 9101 |     buildSingleCopyAssignRecursively(S, Loc, ArrayTy->getElementType(), | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9102 |                                      ToIndex, *FromIndex, CopyingBaseSubobject, | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9103 |                                      Copying, Depth + 1); | 
 | 9104 |   // Bail out if copying fails or if we determined that we should use memcpy. | 
 | 9105 |   if (Copy.isInvalid() || !Copy.get()) | 
 | 9106 |     return Copy; | 
 | 9107 |  | 
 | 9108 |   // Create the comparison against the array bound. | 
 | 9109 |   llvm::APInt Upper | 
 | 9110 |     = ArrayTy->getSize().zextOrTrunc(S.Context.getTypeSize(SizeType)); | 
 | 9111 |   Expr *Comparison | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9112 |     = new (S.Context) BinaryOperator(IterationVarRefRVal.build(S, Loc), | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9113 |                      IntegerLiteral::Create(S.Context, Upper, SizeType, Loc), | 
 | 9114 |                                      BO_NE, S.Context.BoolTy, | 
 | 9115 |                                      VK_RValue, OK_Ordinary, Loc, false); | 
 | 9116 |  | 
 | 9117 |   // Create the pre-increment of the iteration variable. | 
 | 9118 |   Expr *Increment | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9119 |     = new (S.Context) UnaryOperator(IterationVarRef.build(S, Loc), UO_PreInc, | 
 | 9120 |                                     SizeType, VK_LValue, OK_Ordinary, Loc); | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9121 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9122 |   // Construct the loop that copies all elements of this array. | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 9123 |   return S.ActOnForStmt(Loc, Loc, InitStmt,  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9124 |                         S.MakeFullExpr(Comparison), | 
| Richard Smith | 4195637 | 2013-01-14 22:39:08 +0000 | [diff] [blame] | 9125 |                         0, S.MakeFullDiscardedValueExpr(Increment), | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 9126 |                         Loc, Copy.take()); | 
| Fariborz Jahanian | c75bc2d | 2009-06-25 21:45:19 +0000 | [diff] [blame] | 9127 | } | 
 | 9128 |  | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9129 | static StmtResult | 
 | 9130 | buildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9131 |                       const ExprBuilder &To, const ExprBuilder &From, | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9132 |                       bool CopyingBaseSubobject, bool Copying) { | 
 | 9133 |   // Maybe we should use a memcpy? | 
 | 9134 |   if (T->isArrayType() && !T.isConstQualified() && !T.isVolatileQualified() && | 
 | 9135 |       T.isTriviallyCopyableType(S.Context)) | 
 | 9136 |     return buildMemcpyForAssignmentOp(S, Loc, T, To, From); | 
 | 9137 |  | 
 | 9138 |   StmtResult Result(buildSingleCopyAssignRecursively(S, Loc, T, To, From, | 
 | 9139 |                                                      CopyingBaseSubobject, | 
 | 9140 |                                                      Copying, 0)); | 
 | 9141 |  | 
 | 9142 |   // If we ended up picking a trivial assignment operator for an array of a | 
 | 9143 |   // non-trivially-copyable class type, just emit a memcpy. | 
 | 9144 |   if (!Result.isInvalid() && !Result.get()) | 
 | 9145 |     return buildMemcpyForAssignmentOp(S, Loc, T, To, From); | 
 | 9146 |  | 
 | 9147 |   return Result; | 
 | 9148 | } | 
 | 9149 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9150 | Sema::ImplicitExceptionSpecification | 
 | 9151 | Sema::ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD) { | 
 | 9152 |   CXXRecordDecl *ClassDecl = MD->getParent(); | 
 | 9153 |  | 
 | 9154 |   ImplicitExceptionSpecification ExceptSpec(*this); | 
 | 9155 |   if (ClassDecl->isInvalidDecl()) | 
 | 9156 |     return ExceptSpec; | 
 | 9157 |  | 
 | 9158 |   const FunctionProtoType *T = MD->getType()->castAs<FunctionProtoType>(); | 
 | 9159 |   assert(T->getNumArgs() == 1 && "not a copy assignment op"); | 
 | 9160 |   unsigned ArgQuals = T->getArgType(0).getNonReferenceType().getCVRQualifiers(); | 
 | 9161 |  | 
| Douglas Gregor | b87786f | 2010-07-01 17:48:08 +0000 | [diff] [blame] | 9162 |   // C++ [except.spec]p14: | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9163 |   //   An implicitly declared special member function (Clause 12) shall have an | 
| Douglas Gregor | b87786f | 2010-07-01 17:48:08 +0000 | [diff] [blame] | 9164 |   //   exception-specification. [...] | 
| Sean Hunt | 661c67a | 2011-06-21 23:42:56 +0000 | [diff] [blame] | 9165 |  | 
 | 9166 |   // It is unspecified whether or not an implicit copy assignment operator | 
 | 9167 |   // attempts to deduplicate calls to assignment operators of virtual bases are | 
 | 9168 |   // made. As such, this exception specification is effectively unspecified. | 
 | 9169 |   // Based on a similar decision made for constness in C++0x, we're erring on | 
 | 9170 |   // the side of assuming such calls to be made regardless of whether they | 
 | 9171 |   // actually happen. | 
| Douglas Gregor | b87786f | 2010-07-01 17:48:08 +0000 | [diff] [blame] | 9172 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), | 
 | 9173 |                                        BaseEnd = ClassDecl->bases_end(); | 
 | 9174 |        Base != BaseEnd; ++Base) { | 
| Sean Hunt | 661c67a | 2011-06-21 23:42:56 +0000 | [diff] [blame] | 9175 |     if (Base->isVirtual()) | 
 | 9176 |       continue; | 
 | 9177 |  | 
| Douglas Gregor | a376d10 | 2010-07-02 21:50:04 +0000 | [diff] [blame] | 9178 |     CXXRecordDecl *BaseClassDecl | 
| Douglas Gregor | b87786f | 2010-07-01 17:48:08 +0000 | [diff] [blame] | 9179 |       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); | 
| Sean Hunt | 661c67a | 2011-06-21 23:42:56 +0000 | [diff] [blame] | 9180 |     if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl, | 
 | 9181 |                                                             ArgQuals, false, 0)) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 9182 |       ExceptSpec.CalledDecl(Base->getLocStart(), CopyAssign); | 
| Douglas Gregor | b87786f | 2010-07-01 17:48:08 +0000 | [diff] [blame] | 9183 |   } | 
| Sean Hunt | 661c67a | 2011-06-21 23:42:56 +0000 | [diff] [blame] | 9184 |  | 
 | 9185 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), | 
 | 9186 |                                        BaseEnd = ClassDecl->vbases_end(); | 
 | 9187 |        Base != BaseEnd; ++Base) { | 
 | 9188 |     CXXRecordDecl *BaseClassDecl | 
 | 9189 |       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); | 
 | 9190 |     if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl, | 
 | 9191 |                                                             ArgQuals, false, 0)) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 9192 |       ExceptSpec.CalledDecl(Base->getLocStart(), CopyAssign); | 
| Sean Hunt | 661c67a | 2011-06-21 23:42:56 +0000 | [diff] [blame] | 9193 |   } | 
 | 9194 |  | 
| Douglas Gregor | b87786f | 2010-07-01 17:48:08 +0000 | [diff] [blame] | 9195 |   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), | 
 | 9196 |                                   FieldEnd = ClassDecl->field_end(); | 
 | 9197 |        Field != FieldEnd; | 
 | 9198 |        ++Field) { | 
| David Blaikie | 262bc18 | 2012-04-30 02:36:29 +0000 | [diff] [blame] | 9199 |     QualType FieldType = Context.getBaseElementType(Field->getType()); | 
| Sean Hunt | 661c67a | 2011-06-21 23:42:56 +0000 | [diff] [blame] | 9200 |     if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) { | 
 | 9201 |       if (CXXMethodDecl *CopyAssign = | 
| Richard Smith | 6a06e5f | 2012-07-18 03:36:00 +0000 | [diff] [blame] | 9202 |           LookupCopyingAssignment(FieldClassDecl, | 
 | 9203 |                                   ArgQuals | FieldType.getCVRQualifiers(), | 
 | 9204 |                                   false, 0)) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 9205 |         ExceptSpec.CalledDecl(Field->getLocation(), CopyAssign); | 
| Abramo Bagnara | cdb8076 | 2011-07-11 08:52:40 +0000 | [diff] [blame] | 9206 |     } | 
| Douglas Gregor | b87786f | 2010-07-01 17:48:08 +0000 | [diff] [blame] | 9207 |   } | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 9208 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9209 |   return ExceptSpec; | 
| Sean Hunt | 30de05c | 2011-05-14 05:23:20 +0000 | [diff] [blame] | 9210 | } | 
 | 9211 |  | 
 | 9212 | CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) { | 
 | 9213 |   // Note: The following rules are largely analoguous to the copy | 
 | 9214 |   // constructor rules. Note that virtual bases are not taken into account | 
 | 9215 |   // for determining the argument type of the operator. Note also that | 
 | 9216 |   // operators taking an object instead of a reference are allowed. | 
| Richard Smith | e5411b7 | 2012-12-01 02:35:44 +0000 | [diff] [blame] | 9217 |   assert(ClassDecl->needsImplicitCopyAssignment()); | 
| Sean Hunt | 30de05c | 2011-05-14 05:23:20 +0000 | [diff] [blame] | 9218 |  | 
| Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 9219 |   DeclaringSpecialMember DSM(*this, ClassDecl, CXXCopyAssignment); | 
 | 9220 |   if (DSM.isAlreadyBeingDeclared()) | 
 | 9221 |     return 0; | 
 | 9222 |  | 
| Sean Hunt | 30de05c | 2011-05-14 05:23:20 +0000 | [diff] [blame] | 9223 |   QualType ArgType = Context.getTypeDeclType(ClassDecl); | 
 | 9224 |   QualType RetType = Context.getLValueReferenceType(ArgType); | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 9225 |   bool Const = ClassDecl->implicitCopyAssignmentHasConstParam(); | 
 | 9226 |   if (Const) | 
| Sean Hunt | 30de05c | 2011-05-14 05:23:20 +0000 | [diff] [blame] | 9227 |     ArgType = ArgType.withConst(); | 
 | 9228 |   ArgType = Context.getLValueReferenceType(ArgType); | 
 | 9229 |  | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 9230 |   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl, | 
 | 9231 |                                                      CXXCopyAssignment, | 
 | 9232 |                                                      Const); | 
 | 9233 |  | 
| Douglas Gregor | d3c3590 | 2010-07-01 16:36:15 +0000 | [diff] [blame] | 9234 |   //   An implicitly-declared copy assignment operator is an inline public | 
 | 9235 |   //   member of its class. | 
 | 9236 |   DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal); | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 9237 |   SourceLocation ClassLoc = ClassDecl->getLocation(); | 
 | 9238 |   DeclarationNameInfo NameInfo(Name, ClassLoc); | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 9239 |   CXXMethodDecl *CopyAssignment = | 
 | 9240 |       CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, QualType(), | 
 | 9241 |                             /*TInfo=*/ 0, /*StorageClass=*/ SC_None, | 
 | 9242 |                             /*isInline=*/ true, Constexpr, SourceLocation()); | 
| Douglas Gregor | d3c3590 | 2010-07-01 16:36:15 +0000 | [diff] [blame] | 9243 |   CopyAssignment->setAccess(AS_public); | 
| Sean Hunt | 7f41019 | 2011-05-14 05:23:24 +0000 | [diff] [blame] | 9244 |   CopyAssignment->setDefaulted(); | 
| Douglas Gregor | d3c3590 | 2010-07-01 16:36:15 +0000 | [diff] [blame] | 9245 |   CopyAssignment->setImplicit(); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9246 |  | 
 | 9247 |   // Build an exception specification pointing back at this member. | 
| Reid Kleckner | ef07203 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 9248 |   FunctionProtoType::ExtProtoInfo EPI = | 
 | 9249 |       getImplicitMethodEPI(*this, CopyAssignment); | 
| Jordan Rose | bea522f | 2013-03-08 21:51:21 +0000 | [diff] [blame] | 9250 |   CopyAssignment->setType(Context.getFunctionType(RetType, ArgType, EPI)); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9251 |  | 
| Douglas Gregor | d3c3590 | 2010-07-01 16:36:15 +0000 | [diff] [blame] | 9252 |   // Add the parameter to the operator. | 
 | 9253 |   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyAssignment, | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 9254 |                                                ClassLoc, ClassLoc, /*Id=*/0, | 
| Douglas Gregor | d3c3590 | 2010-07-01 16:36:15 +0000 | [diff] [blame] | 9255 |                                                ArgType, /*TInfo=*/0, | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 9256 |                                                SC_None, 0); | 
| David Blaikie | 4278c65 | 2011-09-21 18:16:56 +0000 | [diff] [blame] | 9257 |   CopyAssignment->setParams(FromParam); | 
| Sean Hunt | 7f41019 | 2011-05-14 05:23:24 +0000 | [diff] [blame] | 9258 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 9259 |   AddOverriddenMethods(ClassDecl, CopyAssignment); | 
 | 9260 |  | 
 | 9261 |   CopyAssignment->setTrivial( | 
 | 9262 |     ClassDecl->needsOverloadResolutionForCopyAssignment() | 
 | 9263 |       ? SpecialMemberIsTrivial(CopyAssignment, CXXCopyAssignment) | 
 | 9264 |       : ClassDecl->hasTrivialCopyAssignment()); | 
 | 9265 |  | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 9266 |   // C++11 [class.copy]p19: | 
| Nico Weber | afcc96a | 2012-01-23 03:19:29 +0000 | [diff] [blame] | 9267 |   //   ....  If the class definition does not explicitly declare a copy | 
 | 9268 |   //   assignment operator, there is no user-declared move constructor, and | 
 | 9269 |   //   there is no user-declared move assignment operator, a copy assignment | 
 | 9270 |   //   operator is implicitly declared as defaulted. | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 9271 |   if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment)) | 
| Richard Smith | 0ab5b4c | 2013-04-02 19:38:47 +0000 | [diff] [blame] | 9272 |     SetDeclDeleted(CopyAssignment, ClassLoc); | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 9273 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 9274 |   // Note that we have added this copy-assignment operator. | 
 | 9275 |   ++ASTContext::NumImplicitCopyAssignmentOperatorsDeclared; | 
 | 9276 |  | 
 | 9277 |   if (Scope *S = getScopeForContext(ClassDecl)) | 
 | 9278 |     PushOnScopeChains(CopyAssignment, S, false); | 
 | 9279 |   ClassDecl->addDecl(CopyAssignment); | 
 | 9280 |  | 
| Douglas Gregor | d3c3590 | 2010-07-01 16:36:15 +0000 | [diff] [blame] | 9281 |   return CopyAssignment; | 
 | 9282 | } | 
 | 9283 |  | 
| Richard Smith | 36155c1 | 2013-06-13 03:23:42 +0000 | [diff] [blame] | 9284 | /// Diagnose an implicit copy operation for a class which is odr-used, but | 
 | 9285 | /// which is deprecated because the class has a user-declared copy constructor, | 
 | 9286 | /// copy assignment operator, or destructor. | 
 | 9287 | static void diagnoseDeprecatedCopyOperation(Sema &S, CXXMethodDecl *CopyOp, | 
 | 9288 |                                             SourceLocation UseLoc) { | 
 | 9289 |   assert(CopyOp->isImplicit()); | 
 | 9290 |  | 
 | 9291 |   CXXRecordDecl *RD = CopyOp->getParent(); | 
 | 9292 |   CXXMethodDecl *UserDeclaredOperation = 0; | 
 | 9293 |  | 
 | 9294 |   // In Microsoft mode, assignment operations don't affect constructors and | 
 | 9295 |   // vice versa. | 
 | 9296 |   if (RD->hasUserDeclaredDestructor()) { | 
 | 9297 |     UserDeclaredOperation = RD->getDestructor(); | 
 | 9298 |   } else if (!isa<CXXConstructorDecl>(CopyOp) && | 
 | 9299 |              RD->hasUserDeclaredCopyConstructor() && | 
 | 9300 |              !S.getLangOpts().MicrosoftMode) { | 
 | 9301 |     // Find any user-declared copy constructor. | 
 | 9302 |     for (CXXRecordDecl::ctor_iterator I = RD->ctor_begin(), | 
 | 9303 |                                       E = RD->ctor_end(); I != E; ++I) { | 
 | 9304 |       if (I->isCopyConstructor()) { | 
 | 9305 |         UserDeclaredOperation = *I; | 
 | 9306 |         break; | 
 | 9307 |       } | 
 | 9308 |     } | 
 | 9309 |     assert(UserDeclaredOperation); | 
 | 9310 |   } else if (isa<CXXConstructorDecl>(CopyOp) && | 
 | 9311 |              RD->hasUserDeclaredCopyAssignment() && | 
 | 9312 |              !S.getLangOpts().MicrosoftMode) { | 
 | 9313 |     // Find any user-declared move assignment operator. | 
 | 9314 |     for (CXXRecordDecl::method_iterator I = RD->method_begin(), | 
 | 9315 |                                         E = RD->method_end(); I != E; ++I) { | 
 | 9316 |       if (I->isCopyAssignmentOperator()) { | 
 | 9317 |         UserDeclaredOperation = *I; | 
 | 9318 |         break; | 
 | 9319 |       } | 
 | 9320 |     } | 
 | 9321 |     assert(UserDeclaredOperation); | 
 | 9322 |   } | 
 | 9323 |  | 
 | 9324 |   if (UserDeclaredOperation) { | 
 | 9325 |     S.Diag(UserDeclaredOperation->getLocation(), | 
 | 9326 |          diag::warn_deprecated_copy_operation) | 
 | 9327 |       << RD << /*copy assignment*/!isa<CXXConstructorDecl>(CopyOp) | 
 | 9328 |       << /*destructor*/isa<CXXDestructorDecl>(UserDeclaredOperation); | 
 | 9329 |     S.Diag(UseLoc, diag::note_member_synthesized_at) | 
 | 9330 |       << (isa<CXXConstructorDecl>(CopyOp) ? Sema::CXXCopyConstructor | 
 | 9331 |                                           : Sema::CXXCopyAssignment) | 
 | 9332 |       << RD; | 
 | 9333 |   } | 
 | 9334 | } | 
 | 9335 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9336 | void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, | 
 | 9337 |                                         CXXMethodDecl *CopyAssignOperator) { | 
| Sean Hunt | 7f41019 | 2011-05-14 05:23:24 +0000 | [diff] [blame] | 9338 |   assert((CopyAssignOperator->isDefaulted() &&  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9339 |           CopyAssignOperator->isOverloadedOperator() && | 
 | 9340 |           CopyAssignOperator->getOverloadedOperator() == OO_Equal && | 
| Richard Smith | 03f6878 | 2012-02-26 07:51:39 +0000 | [diff] [blame] | 9341 |           !CopyAssignOperator->doesThisDeclarationHaveABody() && | 
 | 9342 |           !CopyAssignOperator->isDeleted()) && | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9343 |          "DefineImplicitCopyAssignment called for wrong function"); | 
 | 9344 |  | 
 | 9345 |   CXXRecordDecl *ClassDecl = CopyAssignOperator->getParent(); | 
 | 9346 |  | 
 | 9347 |   if (ClassDecl->isInvalidDecl() || CopyAssignOperator->isInvalidDecl()) { | 
 | 9348 |     CopyAssignOperator->setInvalidDecl(); | 
 | 9349 |     return; | 
 | 9350 |   } | 
| Richard Smith | 36155c1 | 2013-06-13 03:23:42 +0000 | [diff] [blame] | 9351 |  | 
 | 9352 |   // C++11 [class.copy]p18: | 
 | 9353 |   //   The [definition of an implicitly declared copy assignment operator] is | 
 | 9354 |   //   deprecated if the class has a user-declared copy constructor or a | 
 | 9355 |   //   user-declared destructor. | 
 | 9356 |   if (getLangOpts().CPlusPlus11 && CopyAssignOperator->isImplicit()) | 
 | 9357 |     diagnoseDeprecatedCopyOperation(*this, CopyAssignOperator, CurrentLocation); | 
 | 9358 |  | 
| Eli Friedman | 86164e8 | 2013-09-05 00:02:25 +0000 | [diff] [blame] | 9359 |   CopyAssignOperator->markUsed(Context); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9360 |  | 
| Eli Friedman | 9a14db3 | 2012-10-18 20:14:08 +0000 | [diff] [blame] | 9361 |   SynthesizedFunctionScope Scope(*this, CopyAssignOperator); | 
| Argyrios Kyrtzidis | 9c4eb1f | 2010-11-19 00:19:12 +0000 | [diff] [blame] | 9362 |   DiagnosticErrorTrap Trap(Diags); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9363 |  | 
 | 9364 |   // C++0x [class.copy]p30: | 
 | 9365 |   //   The implicitly-defined or explicitly-defaulted copy assignment operator | 
 | 9366 |   //   for a non-union class X performs memberwise copy assignment of its  | 
 | 9367 |   //   subobjects. The direct base classes of X are assigned first, in the  | 
 | 9368 |   //   order of their declaration in the base-specifier-list, and then the  | 
 | 9369 |   //   immediate non-static data members of X are assigned, in the order in  | 
 | 9370 |   //   which they were declared in the class definition. | 
 | 9371 |    | 
 | 9372 |   // The statements that form the synthesized function body. | 
| Benjamin Kramer | 4e28d9e | 2012-08-23 22:51:59 +0000 | [diff] [blame] | 9373 |   SmallVector<Stmt*, 8> Statements; | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9374 |    | 
 | 9375 |   // The parameter for the "other" object, which we are copying from. | 
 | 9376 |   ParmVarDecl *Other = CopyAssignOperator->getParamDecl(0); | 
 | 9377 |   Qualifiers OtherQuals = Other->getType().getQualifiers(); | 
 | 9378 |   QualType OtherRefType = Other->getType(); | 
 | 9379 |   if (const LValueReferenceType *OtherRef | 
 | 9380 |                                 = OtherRefType->getAs<LValueReferenceType>()) { | 
 | 9381 |     OtherRefType = OtherRef->getPointeeType(); | 
 | 9382 |     OtherQuals = OtherRefType.getQualifiers(); | 
 | 9383 |   } | 
 | 9384 |    | 
 | 9385 |   // Our location for everything implicitly-generated. | 
 | 9386 |   SourceLocation Loc = CopyAssignOperator->getLocation(); | 
 | 9387 |    | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9388 |   // Builds a DeclRefExpr for the "other" object. | 
 | 9389 |   RefBuilder OtherRef(Other, OtherRefType); | 
 | 9390 |  | 
 | 9391 |   // Builds the "this" pointer. | 
 | 9392 |   ThisBuilder This; | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9393 |    | 
 | 9394 |   // Assign base classes. | 
 | 9395 |   bool Invalid = false; | 
 | 9396 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), | 
 | 9397 |        E = ClassDecl->bases_end(); Base != E; ++Base) { | 
 | 9398 |     // Form the assignment: | 
 | 9399 |     //   static_cast<Base*>(this)->Base::operator=(static_cast<Base&>(other)); | 
 | 9400 |     QualType BaseType = Base->getType().getUnqualifiedType(); | 
| Jeffrey Yasskin | dec0984 | 2011-01-18 02:00:16 +0000 | [diff] [blame] | 9401 |     if (!BaseType->isRecordType()) { | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9402 |       Invalid = true; | 
 | 9403 |       continue; | 
 | 9404 |     } | 
 | 9405 |  | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 9406 |     CXXCastPath BasePath; | 
 | 9407 |     BasePath.push_back(Base); | 
 | 9408 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9409 |     // Construct the "from" expression, which is an implicit cast to the | 
 | 9410 |     // appropriately-qualified base type. | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9411 |     CastBuilder From(OtherRef, Context.getQualifiedType(BaseType, OtherQuals), | 
 | 9412 |                      VK_LValue, BasePath); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9413 |  | 
 | 9414 |     // Dereference "this". | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9415 |     DerefBuilder DerefThis(This); | 
 | 9416 |     CastBuilder To(DerefThis, | 
 | 9417 |                    Context.getCVRQualifiedType( | 
 | 9418 |                        BaseType, CopyAssignOperator->getTypeQualifiers()), | 
 | 9419 |                    VK_LValue, BasePath); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9420 |  | 
 | 9421 |     // Build the copy. | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9422 |     StmtResult Copy = buildSingleCopyAssign(*this, Loc, BaseType, | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9423 |                                             To, From, | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9424 |                                             /*CopyingBaseSubobject=*/true, | 
 | 9425 |                                             /*Copying=*/true); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9426 |     if (Copy.isInvalid()) { | 
| Douglas Gregor | 60a8fbb | 2010-05-05 22:38:15 +0000 | [diff] [blame] | 9427 |       Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9428 |         << CXXCopyAssignment << Context.getTagDeclType(ClassDecl); | 
 | 9429 |       CopyAssignOperator->setInvalidDecl(); | 
 | 9430 |       return; | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9431 |     } | 
 | 9432 |      | 
 | 9433 |     // Success! Record the copy. | 
 | 9434 |     Statements.push_back(Copy.takeAs<Expr>()); | 
 | 9435 |   } | 
 | 9436 |    | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9437 |   // Assign non-static members. | 
 | 9438 |   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), | 
 | 9439 |                                   FieldEnd = ClassDecl->field_end();  | 
 | 9440 |        Field != FieldEnd; ++Field) { | 
| Douglas Gregor | d61db33 | 2011-10-10 17:22:13 +0000 | [diff] [blame] | 9441 |     if (Field->isUnnamedBitfield()) | 
 | 9442 |       continue; | 
| Eli Friedman | 8150da3 | 2013-06-07 01:48:56 +0000 | [diff] [blame] | 9443 |  | 
 | 9444 |     if (Field->isInvalidDecl()) { | 
 | 9445 |       Invalid = true; | 
 | 9446 |       continue; | 
 | 9447 |     } | 
 | 9448 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9449 |     // Check for members of reference type; we can't copy those. | 
 | 9450 |     if (Field->getType()->isReferenceType()) { | 
 | 9451 |       Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign) | 
 | 9452 |         << Context.getTagDeclType(ClassDecl) << 0 << Field->getDeclName(); | 
 | 9453 |       Diag(Field->getLocation(), diag::note_declared_at); | 
| Douglas Gregor | 60a8fbb | 2010-05-05 22:38:15 +0000 | [diff] [blame] | 9454 |       Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9455 |         << CXXCopyAssignment << Context.getTagDeclType(ClassDecl); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9456 |       Invalid = true; | 
 | 9457 |       continue; | 
 | 9458 |     } | 
 | 9459 |      | 
 | 9460 |     // Check for members of const-qualified, non-class type. | 
 | 9461 |     QualType BaseType = Context.getBaseElementType(Field->getType()); | 
 | 9462 |     if (!BaseType->getAs<RecordType>() && BaseType.isConstQualified()) { | 
 | 9463 |       Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign) | 
 | 9464 |         << Context.getTagDeclType(ClassDecl) << 1 << Field->getDeclName(); | 
 | 9465 |       Diag(Field->getLocation(), diag::note_declared_at); | 
| Douglas Gregor | 60a8fbb | 2010-05-05 22:38:15 +0000 | [diff] [blame] | 9466 |       Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9467 |         << CXXCopyAssignment << Context.getTagDeclType(ClassDecl); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9468 |       Invalid = true;       | 
 | 9469 |       continue; | 
 | 9470 |     } | 
| John McCall | b77115d | 2011-06-17 00:18:42 +0000 | [diff] [blame] | 9471 |  | 
 | 9472 |     // Suppress assigning zero-width bitfields. | 
| Richard Smith | a6b8b2c | 2011-10-10 18:28:20 +0000 | [diff] [blame] | 9473 |     if (Field->isBitField() && Field->getBitWidthValue(Context) == 0) | 
 | 9474 |       continue; | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9475 |      | 
 | 9476 |     QualType FieldType = Field->getType().getNonReferenceType(); | 
| Fariborz Jahanian | 4142ceb | 2010-05-26 20:19:07 +0000 | [diff] [blame] | 9477 |     if (FieldType->isIncompleteArrayType()) { | 
 | 9478 |       assert(ClassDecl->hasFlexibleArrayMember() &&  | 
 | 9479 |              "Incomplete array type is not valid"); | 
 | 9480 |       continue; | 
 | 9481 |     } | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9482 |      | 
 | 9483 |     // Build references to the field in the object we're copying from and to. | 
 | 9484 |     CXXScopeSpec SS; // Intentionally empty | 
 | 9485 |     LookupResult MemberLookup(*this, Field->getDeclName(), Loc, | 
 | 9486 |                               LookupMemberName); | 
| David Blaikie | 581deb3 | 2012-06-06 20:45:41 +0000 | [diff] [blame] | 9487 |     MemberLookup.addDecl(*Field); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9488 |     MemberLookup.resolveKind(); | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9489 |  | 
 | 9490 |     MemberBuilder From(OtherRef, OtherRefType, /*IsArrow=*/false, MemberLookup); | 
 | 9491 |  | 
 | 9492 |     MemberBuilder To(This, getCurrentThisType(), /*IsArrow=*/true, MemberLookup); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9493 |  | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9494 |     // Build the copy of this field. | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9495 |     StmtResult Copy = buildSingleCopyAssign(*this, Loc, FieldType, | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9496 |                                             To, From, | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9497 |                                             /*CopyingBaseSubobject=*/false, | 
 | 9498 |                                             /*Copying=*/true); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9499 |     if (Copy.isInvalid()) { | 
| Douglas Gregor | 60a8fbb | 2010-05-05 22:38:15 +0000 | [diff] [blame] | 9500 |       Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9501 |         << CXXCopyAssignment << Context.getTagDeclType(ClassDecl); | 
 | 9502 |       CopyAssignOperator->setInvalidDecl(); | 
 | 9503 |       return; | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9504 |     } | 
 | 9505 |      | 
 | 9506 |     // Success! Record the copy. | 
 | 9507 |     Statements.push_back(Copy.takeAs<Stmt>()); | 
 | 9508 |   } | 
 | 9509 |  | 
 | 9510 |   if (!Invalid) { | 
 | 9511 |     // Add a "return *this;" | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9512 |     ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc)); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9513 |      | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 9514 |     StmtResult Return = ActOnReturnStmt(Loc, ThisObj.get()); | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9515 |     if (Return.isInvalid()) | 
 | 9516 |       Invalid = true; | 
 | 9517 |     else { | 
 | 9518 |       Statements.push_back(Return.takeAs<Stmt>()); | 
| Douglas Gregor | c63d2c8 | 2010-05-12 16:39:35 +0000 | [diff] [blame] | 9519 |  | 
 | 9520 |       if (Trap.hasErrorOccurred()) { | 
 | 9521 |         Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9522 |           << CXXCopyAssignment << Context.getTagDeclType(ClassDecl); | 
 | 9523 |         Invalid = true; | 
 | 9524 |       } | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9525 |     } | 
 | 9526 |   } | 
 | 9527 |  | 
 | 9528 |   if (Invalid) { | 
 | 9529 |     CopyAssignOperator->setInvalidDecl(); | 
 | 9530 |     return; | 
 | 9531 |   } | 
| Dmitri Gribenko | 625bb56 | 2012-02-14 22:14:32 +0000 | [diff] [blame] | 9532 |  | 
 | 9533 |   StmtResult Body; | 
 | 9534 |   { | 
 | 9535 |     CompoundScopeRAII CompoundScope(*this); | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 9536 |     Body = ActOnCompoundStmt(Loc, Loc, Statements, | 
| Dmitri Gribenko | 625bb56 | 2012-02-14 22:14:32 +0000 | [diff] [blame] | 9537 |                              /*isStmtExpr=*/false); | 
 | 9538 |     assert(!Body.isInvalid() && "Compound statement creation cannot fail"); | 
 | 9539 |   } | 
| Douglas Gregor | 06a9f36 | 2010-05-01 20:49:11 +0000 | [diff] [blame] | 9540 |   CopyAssignOperator->setBody(Body.takeAs<Stmt>()); | 
| Sebastian Redl | 58a2cd8 | 2011-04-24 16:28:06 +0000 | [diff] [blame] | 9541 |  | 
 | 9542 |   if (ASTMutationListener *L = getASTMutationListener()) { | 
 | 9543 |     L->CompletedImplicitDefinition(CopyAssignOperator); | 
 | 9544 |   } | 
| Fariborz Jahanian | c75bc2d | 2009-06-25 21:45:19 +0000 | [diff] [blame] | 9545 | } | 
 | 9546 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9547 | Sema::ImplicitExceptionSpecification | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9548 | Sema::ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD) { | 
 | 9549 |   CXXRecordDecl *ClassDecl = MD->getParent(); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9550 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9551 |   ImplicitExceptionSpecification ExceptSpec(*this); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9552 |   if (ClassDecl->isInvalidDecl()) | 
 | 9553 |     return ExceptSpec; | 
 | 9554 |  | 
 | 9555 |   // C++0x [except.spec]p14: | 
 | 9556 |   //   An implicitly declared special member function (Clause 12) shall have an  | 
 | 9557 |   //   exception-specification. [...] | 
 | 9558 |  | 
 | 9559 |   // It is unspecified whether or not an implicit move assignment operator | 
 | 9560 |   // attempts to deduplicate calls to assignment operators of virtual bases are | 
 | 9561 |   // made. As such, this exception specification is effectively unspecified. | 
 | 9562 |   // Based on a similar decision made for constness in C++0x, we're erring on | 
 | 9563 |   // the side of assuming such calls to be made regardless of whether they | 
 | 9564 |   // actually happen. | 
 | 9565 |   // Note that a move constructor is not implicitly declared when there are | 
 | 9566 |   // virtual bases, but it can still be user-declared and explicitly defaulted. | 
 | 9567 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), | 
 | 9568 |                                        BaseEnd = ClassDecl->bases_end(); | 
 | 9569 |        Base != BaseEnd; ++Base) { | 
 | 9570 |     if (Base->isVirtual()) | 
 | 9571 |       continue; | 
 | 9572 |  | 
 | 9573 |     CXXRecordDecl *BaseClassDecl | 
 | 9574 |       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); | 
 | 9575 |     if (CXXMethodDecl *MoveAssign = LookupMovingAssignment(BaseClassDecl, | 
| Richard Smith | 6a06e5f | 2012-07-18 03:36:00 +0000 | [diff] [blame] | 9576 |                                                            0, false, 0)) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 9577 |       ExceptSpec.CalledDecl(Base->getLocStart(), MoveAssign); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9578 |   } | 
 | 9579 |  | 
 | 9580 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), | 
 | 9581 |                                        BaseEnd = ClassDecl->vbases_end(); | 
 | 9582 |        Base != BaseEnd; ++Base) { | 
 | 9583 |     CXXRecordDecl *BaseClassDecl | 
 | 9584 |       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); | 
 | 9585 |     if (CXXMethodDecl *MoveAssign = LookupMovingAssignment(BaseClassDecl, | 
| Richard Smith | 6a06e5f | 2012-07-18 03:36:00 +0000 | [diff] [blame] | 9586 |                                                            0, false, 0)) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 9587 |       ExceptSpec.CalledDecl(Base->getLocStart(), MoveAssign); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9588 |   } | 
 | 9589 |  | 
 | 9590 |   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), | 
 | 9591 |                                   FieldEnd = ClassDecl->field_end(); | 
 | 9592 |        Field != FieldEnd; | 
 | 9593 |        ++Field) { | 
| David Blaikie | 262bc18 | 2012-04-30 02:36:29 +0000 | [diff] [blame] | 9594 |     QualType FieldType = Context.getBaseElementType(Field->getType()); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9595 |     if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) { | 
| Richard Smith | 6a06e5f | 2012-07-18 03:36:00 +0000 | [diff] [blame] | 9596 |       if (CXXMethodDecl *MoveAssign = | 
 | 9597 |               LookupMovingAssignment(FieldClassDecl, | 
 | 9598 |                                      FieldType.getCVRQualifiers(), | 
 | 9599 |                                      false, 0)) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 9600 |         ExceptSpec.CalledDecl(Field->getLocation(), MoveAssign); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9601 |     } | 
 | 9602 |   } | 
 | 9603 |  | 
 | 9604 |   return ExceptSpec; | 
 | 9605 | } | 
 | 9606 |  | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9607 | /// Determine whether the class type has any direct or indirect virtual base | 
 | 9608 | /// classes which have a non-trivial move assignment operator. | 
 | 9609 | static bool | 
 | 9610 | hasVirtualBaseWithNonTrivialMoveAssignment(Sema &S, CXXRecordDecl *ClassDecl) { | 
 | 9611 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), | 
 | 9612 |                                           BaseEnd = ClassDecl->vbases_end(); | 
 | 9613 |        Base != BaseEnd; ++Base) { | 
 | 9614 |     CXXRecordDecl *BaseClass = | 
 | 9615 |         cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); | 
 | 9616 |  | 
 | 9617 |     // Try to declare the move assignment. If it would be deleted, then the | 
 | 9618 |     // class does not have a non-trivial move assignment. | 
 | 9619 |     if (BaseClass->needsImplicitMoveAssignment()) | 
 | 9620 |       S.DeclareImplicitMoveAssignment(BaseClass); | 
 | 9621 |  | 
| Richard Smith | 426391c | 2012-11-16 00:53:38 +0000 | [diff] [blame] | 9622 |     if (BaseClass->hasNonTrivialMoveAssignment()) | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9623 |       return true; | 
 | 9624 |   } | 
 | 9625 |  | 
 | 9626 |   return false; | 
 | 9627 | } | 
 | 9628 |  | 
 | 9629 | /// Determine whether the given type either has a move constructor or is | 
 | 9630 | /// trivially copyable. | 
 | 9631 | static bool | 
 | 9632 | hasMoveOrIsTriviallyCopyable(Sema &S, QualType Type, bool IsConstructor) { | 
 | 9633 |   Type = S.Context.getBaseElementType(Type); | 
 | 9634 |  | 
 | 9635 |   // FIXME: Technically, non-trivially-copyable non-class types, such as | 
 | 9636 |   // reference types, are supposed to return false here, but that appears | 
 | 9637 |   // to be a standard defect. | 
 | 9638 |   CXXRecordDecl *ClassDecl = Type->getAsCXXRecordDecl(); | 
| Argyrios Kyrtzidis | b5e4ace | 2012-10-10 16:14:06 +0000 | [diff] [blame] | 9639 |   if (!ClassDecl || !ClassDecl->getDefinition() || ClassDecl->isInvalidDecl()) | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9640 |     return true; | 
 | 9641 |  | 
 | 9642 |   if (Type.isTriviallyCopyableType(S.Context)) | 
 | 9643 |     return true; | 
 | 9644 |  | 
 | 9645 |   if (IsConstructor) { | 
| Richard Smith | e5411b7 | 2012-12-01 02:35:44 +0000 | [diff] [blame] | 9646 |     // FIXME: Need this because otherwise hasMoveConstructor isn't guaranteed to | 
 | 9647 |     // give the right answer. | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9648 |     if (ClassDecl->needsImplicitMoveConstructor()) | 
 | 9649 |       S.DeclareImplicitMoveConstructor(ClassDecl); | 
| Richard Smith | e5411b7 | 2012-12-01 02:35:44 +0000 | [diff] [blame] | 9650 |     return ClassDecl->hasMoveConstructor(); | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9651 |   } | 
 | 9652 |  | 
| Richard Smith | e5411b7 | 2012-12-01 02:35:44 +0000 | [diff] [blame] | 9653 |   // FIXME: Need this because otherwise hasMoveAssignment isn't guaranteed to | 
 | 9654 |   // give the right answer. | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9655 |   if (ClassDecl->needsImplicitMoveAssignment()) | 
 | 9656 |     S.DeclareImplicitMoveAssignment(ClassDecl); | 
| Richard Smith | e5411b7 | 2012-12-01 02:35:44 +0000 | [diff] [blame] | 9657 |   return ClassDecl->hasMoveAssignment(); | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9658 | } | 
 | 9659 |  | 
 | 9660 | /// Determine whether all non-static data members and direct or virtual bases | 
 | 9661 | /// of class \p ClassDecl have either a move operation, or are trivially | 
 | 9662 | /// copyable. | 
 | 9663 | static bool subobjectsHaveMoveOrTrivialCopy(Sema &S, CXXRecordDecl *ClassDecl, | 
 | 9664 |                                             bool IsConstructor) { | 
 | 9665 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), | 
 | 9666 |                                           BaseEnd = ClassDecl->bases_end(); | 
 | 9667 |        Base != BaseEnd; ++Base) { | 
 | 9668 |     if (Base->isVirtual()) | 
 | 9669 |       continue; | 
 | 9670 |  | 
 | 9671 |     if (!hasMoveOrIsTriviallyCopyable(S, Base->getType(), IsConstructor)) | 
 | 9672 |       return false; | 
 | 9673 |   } | 
 | 9674 |  | 
 | 9675 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), | 
 | 9676 |                                           BaseEnd = ClassDecl->vbases_end(); | 
 | 9677 |        Base != BaseEnd; ++Base) { | 
 | 9678 |     if (!hasMoveOrIsTriviallyCopyable(S, Base->getType(), IsConstructor)) | 
 | 9679 |       return false; | 
 | 9680 |   } | 
 | 9681 |  | 
 | 9682 |   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), | 
 | 9683 |                                      FieldEnd = ClassDecl->field_end(); | 
 | 9684 |        Field != FieldEnd; ++Field) { | 
| David Blaikie | 262bc18 | 2012-04-30 02:36:29 +0000 | [diff] [blame] | 9685 |     if (!hasMoveOrIsTriviallyCopyable(S, Field->getType(), IsConstructor)) | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9686 |       return false; | 
 | 9687 |   } | 
 | 9688 |  | 
 | 9689 |   return true; | 
 | 9690 | } | 
 | 9691 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9692 | CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) { | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9693 |   // C++11 [class.copy]p20: | 
 | 9694 |   //   If the definition of a class X does not explicitly declare a move | 
 | 9695 |   //   assignment operator, one will be implicitly declared as defaulted | 
 | 9696 |   //   if and only if: | 
 | 9697 |   // | 
 | 9698 |   //   - [first 4 bullets] | 
 | 9699 |   assert(ClassDecl->needsImplicitMoveAssignment()); | 
 | 9700 |  | 
| Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 9701 |   DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveAssignment); | 
 | 9702 |   if (DSM.isAlreadyBeingDeclared()) | 
 | 9703 |     return 0; | 
 | 9704 |  | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9705 |   // [Checked after we build the declaration] | 
 | 9706 |   //   - the move assignment operator would not be implicitly defined as | 
 | 9707 |   //     deleted, | 
 | 9708 |  | 
 | 9709 |   // [DR1402]: | 
 | 9710 |   //   - X has no direct or indirect virtual base class with a non-trivial | 
 | 9711 |   //     move assignment operator, and | 
 | 9712 |   //   - each of X's non-static data members and direct or virtual base classes | 
 | 9713 |   //     has a type that either has a move assignment operator or is trivially | 
 | 9714 |   //     copyable. | 
 | 9715 |   if (hasVirtualBaseWithNonTrivialMoveAssignment(*this, ClassDecl) || | 
 | 9716 |       !subobjectsHaveMoveOrTrivialCopy(*this, ClassDecl,/*Constructor*/false)) { | 
 | 9717 |     ClassDecl->setFailedImplicitMoveAssignment(); | 
 | 9718 |     return 0; | 
 | 9719 |   } | 
 | 9720 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9721 |   // Note: The following rules are largely analoguous to the move | 
 | 9722 |   // constructor rules. | 
 | 9723 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9724 |   QualType ArgType = Context.getTypeDeclType(ClassDecl); | 
 | 9725 |   QualType RetType = Context.getLValueReferenceType(ArgType); | 
 | 9726 |   ArgType = Context.getRValueReferenceType(ArgType); | 
 | 9727 |  | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 9728 |   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl, | 
 | 9729 |                                                      CXXMoveAssignment, | 
 | 9730 |                                                      false); | 
 | 9731 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9732 |   //   An implicitly-declared move assignment operator is an inline public | 
 | 9733 |   //   member of its class. | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9734 |   DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal); | 
 | 9735 |   SourceLocation ClassLoc = ClassDecl->getLocation(); | 
 | 9736 |   DeclarationNameInfo NameInfo(Name, ClassLoc); | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 9737 |   CXXMethodDecl *MoveAssignment = | 
 | 9738 |       CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, QualType(), | 
 | 9739 |                             /*TInfo=*/0, /*StorageClass=*/SC_None, | 
 | 9740 |                             /*isInline=*/true, Constexpr, SourceLocation()); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9741 |   MoveAssignment->setAccess(AS_public); | 
 | 9742 |   MoveAssignment->setDefaulted(); | 
 | 9743 |   MoveAssignment->setImplicit(); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9744 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9745 |   // Build an exception specification pointing back at this member. | 
| Reid Kleckner | ef07203 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 9746 |   FunctionProtoType::ExtProtoInfo EPI = | 
 | 9747 |       getImplicitMethodEPI(*this, MoveAssignment); | 
| Jordan Rose | bea522f | 2013-03-08 21:51:21 +0000 | [diff] [blame] | 9748 |   MoveAssignment->setType(Context.getFunctionType(RetType, ArgType, EPI)); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9749 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9750 |   // Add the parameter to the operator. | 
 | 9751 |   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveAssignment, | 
 | 9752 |                                                ClassLoc, ClassLoc, /*Id=*/0, | 
 | 9753 |                                                ArgType, /*TInfo=*/0, | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9754 |                                                SC_None, 0); | 
| David Blaikie | 4278c65 | 2011-09-21 18:16:56 +0000 | [diff] [blame] | 9755 |   MoveAssignment->setParams(FromParam); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9756 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 9757 |   AddOverriddenMethods(ClassDecl, MoveAssignment); | 
 | 9758 |  | 
 | 9759 |   MoveAssignment->setTrivial( | 
 | 9760 |     ClassDecl->needsOverloadResolutionForMoveAssignment() | 
 | 9761 |       ? SpecialMemberIsTrivial(MoveAssignment, CXXMoveAssignment) | 
 | 9762 |       : ClassDecl->hasTrivialMoveAssignment()); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9763 |  | 
 | 9764 |   // C++0x [class.copy]p9: | 
 | 9765 |   //   If the definition of a class X does not explicitly declare a move | 
 | 9766 |   //   assignment operator, one will be implicitly declared as defaulted if and | 
 | 9767 |   //   only if: | 
 | 9768 |   //   [...] | 
 | 9769 |   //   - the move assignment operator would not be implicitly defined as | 
 | 9770 |   //     deleted. | 
| Richard Smith | 7d5088a | 2012-02-18 02:02:13 +0000 | [diff] [blame] | 9771 |   if (ShouldDeleteSpecialMember(MoveAssignment, CXXMoveAssignment)) { | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9772 |     // Cache this result so that we don't try to generate this over and over | 
 | 9773 |     // on every lookup, leaking memory and wasting time. | 
 | 9774 |     ClassDecl->setFailedImplicitMoveAssignment(); | 
 | 9775 |     return 0; | 
 | 9776 |   } | 
 | 9777 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 9778 |   // Note that we have added this copy-assignment operator. | 
 | 9779 |   ++ASTContext::NumImplicitMoveAssignmentOperatorsDeclared; | 
 | 9780 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9781 |   if (Scope *S = getScopeForContext(ClassDecl)) | 
 | 9782 |     PushOnScopeChains(MoveAssignment, S, false); | 
 | 9783 |   ClassDecl->addDecl(MoveAssignment); | 
 | 9784 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9785 |   return MoveAssignment; | 
 | 9786 | } | 
 | 9787 |  | 
 | 9788 | void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, | 
 | 9789 |                                         CXXMethodDecl *MoveAssignOperator) { | 
 | 9790 |   assert((MoveAssignOperator->isDefaulted() &&  | 
 | 9791 |           MoveAssignOperator->isOverloadedOperator() && | 
 | 9792 |           MoveAssignOperator->getOverloadedOperator() == OO_Equal && | 
| Richard Smith | 03f6878 | 2012-02-26 07:51:39 +0000 | [diff] [blame] | 9793 |           !MoveAssignOperator->doesThisDeclarationHaveABody() && | 
 | 9794 |           !MoveAssignOperator->isDeleted()) && | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9795 |          "DefineImplicitMoveAssignment called for wrong function"); | 
 | 9796 |  | 
 | 9797 |   CXXRecordDecl *ClassDecl = MoveAssignOperator->getParent(); | 
 | 9798 |  | 
 | 9799 |   if (ClassDecl->isInvalidDecl() || MoveAssignOperator->isInvalidDecl()) { | 
 | 9800 |     MoveAssignOperator->setInvalidDecl(); | 
 | 9801 |     return; | 
 | 9802 |   } | 
 | 9803 |    | 
| Eli Friedman | 86164e8 | 2013-09-05 00:02:25 +0000 | [diff] [blame] | 9804 |   MoveAssignOperator->markUsed(Context); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9805 |  | 
| Eli Friedman | 9a14db3 | 2012-10-18 20:14:08 +0000 | [diff] [blame] | 9806 |   SynthesizedFunctionScope Scope(*this, MoveAssignOperator); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9807 |   DiagnosticErrorTrap Trap(Diags); | 
 | 9808 |  | 
 | 9809 |   // C++0x [class.copy]p28: | 
 | 9810 |   //   The implicitly-defined or move assignment operator for a non-union class | 
 | 9811 |   //   X performs memberwise move assignment of its subobjects. The direct base | 
 | 9812 |   //   classes of X are assigned first, in the order of their declaration in the | 
 | 9813 |   //   base-specifier-list, and then the immediate non-static data members of X | 
 | 9814 |   //   are assigned, in the order in which they were declared in the class | 
 | 9815 |   //   definition. | 
 | 9816 |  | 
 | 9817 |   // The statements that form the synthesized function body. | 
| Benjamin Kramer | 4e28d9e | 2012-08-23 22:51:59 +0000 | [diff] [blame] | 9818 |   SmallVector<Stmt*, 8> Statements; | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9819 |  | 
 | 9820 |   // The parameter for the "other" object, which we are move from. | 
 | 9821 |   ParmVarDecl *Other = MoveAssignOperator->getParamDecl(0); | 
 | 9822 |   QualType OtherRefType = Other->getType()-> | 
 | 9823 |       getAs<RValueReferenceType>()->getPointeeType(); | 
| David Blaikie | 7247c88 | 2013-05-15 07:37:26 +0000 | [diff] [blame] | 9824 |   assert(!OtherRefType.getQualifiers() && | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9825 |          "Bad argument type of defaulted move assignment"); | 
 | 9826 |  | 
 | 9827 |   // Our location for everything implicitly-generated. | 
 | 9828 |   SourceLocation Loc = MoveAssignOperator->getLocation(); | 
 | 9829 |  | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9830 |   // Builds a reference to the "other" object. | 
 | 9831 |   RefBuilder OtherRef(Other, OtherRefType); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9832 |   // Cast to rvalue. | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9833 |   MoveCastBuilder MoveOther(OtherRef); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9834 |  | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9835 |   // Builds the "this" pointer. | 
 | 9836 |   ThisBuilder This; | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 9837 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9838 |   // Assign base classes. | 
 | 9839 |   bool Invalid = false; | 
 | 9840 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), | 
 | 9841 |        E = ClassDecl->bases_end(); Base != E; ++Base) { | 
 | 9842 |     // Form the assignment: | 
 | 9843 |     //   static_cast<Base*>(this)->Base::operator=(static_cast<Base&&>(other)); | 
 | 9844 |     QualType BaseType = Base->getType().getUnqualifiedType(); | 
 | 9845 |     if (!BaseType->isRecordType()) { | 
 | 9846 |       Invalid = true; | 
 | 9847 |       continue; | 
 | 9848 |     } | 
 | 9849 |  | 
 | 9850 |     CXXCastPath BasePath; | 
 | 9851 |     BasePath.push_back(Base); | 
 | 9852 |  | 
 | 9853 |     // Construct the "from" expression, which is an implicit cast to the | 
 | 9854 |     // appropriately-qualified base type. | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9855 |     CastBuilder From(OtherRef, BaseType, VK_XValue, BasePath); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9856 |  | 
 | 9857 |     // Dereference "this". | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9858 |     DerefBuilder DerefThis(This); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9859 |  | 
 | 9860 |     // Implicitly cast "this" to the appropriately-qualified base type. | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9861 |     CastBuilder To(DerefThis, | 
 | 9862 |                    Context.getCVRQualifiedType( | 
 | 9863 |                        BaseType, MoveAssignOperator->getTypeQualifiers()), | 
 | 9864 |                    VK_LValue, BasePath); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9865 |  | 
 | 9866 |     // Build the move. | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9867 |     StmtResult Move = buildSingleCopyAssign(*this, Loc, BaseType, | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9868 |                                             To, From, | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9869 |                                             /*CopyingBaseSubobject=*/true, | 
 | 9870 |                                             /*Copying=*/false); | 
 | 9871 |     if (Move.isInvalid()) { | 
 | 9872 |       Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9873 |         << CXXMoveAssignment << Context.getTagDeclType(ClassDecl); | 
 | 9874 |       MoveAssignOperator->setInvalidDecl(); | 
 | 9875 |       return; | 
 | 9876 |     } | 
 | 9877 |  | 
 | 9878 |     // Success! Record the move. | 
 | 9879 |     Statements.push_back(Move.takeAs<Expr>()); | 
 | 9880 |   } | 
 | 9881 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9882 |   // Assign non-static members. | 
 | 9883 |   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), | 
 | 9884 |                                   FieldEnd = ClassDecl->field_end();  | 
 | 9885 |        Field != FieldEnd; ++Field) { | 
| Douglas Gregor | d61db33 | 2011-10-10 17:22:13 +0000 | [diff] [blame] | 9886 |     if (Field->isUnnamedBitfield()) | 
 | 9887 |       continue; | 
 | 9888 |  | 
| Eli Friedman | 8150da3 | 2013-06-07 01:48:56 +0000 | [diff] [blame] | 9889 |     if (Field->isInvalidDecl()) { | 
 | 9890 |       Invalid = true; | 
 | 9891 |       continue; | 
 | 9892 |     } | 
 | 9893 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9894 |     // Check for members of reference type; we can't move those. | 
 | 9895 |     if (Field->getType()->isReferenceType()) { | 
 | 9896 |       Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign) | 
 | 9897 |         << Context.getTagDeclType(ClassDecl) << 0 << Field->getDeclName(); | 
 | 9898 |       Diag(Field->getLocation(), diag::note_declared_at); | 
 | 9899 |       Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9900 |         << CXXMoveAssignment << Context.getTagDeclType(ClassDecl); | 
 | 9901 |       Invalid = true; | 
 | 9902 |       continue; | 
 | 9903 |     } | 
 | 9904 |  | 
 | 9905 |     // Check for members of const-qualified, non-class type. | 
 | 9906 |     QualType BaseType = Context.getBaseElementType(Field->getType()); | 
 | 9907 |     if (!BaseType->getAs<RecordType>() && BaseType.isConstQualified()) { | 
 | 9908 |       Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign) | 
 | 9909 |         << Context.getTagDeclType(ClassDecl) << 1 << Field->getDeclName(); | 
 | 9910 |       Diag(Field->getLocation(), diag::note_declared_at); | 
 | 9911 |       Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9912 |         << CXXMoveAssignment << Context.getTagDeclType(ClassDecl); | 
 | 9913 |       Invalid = true;       | 
 | 9914 |       continue; | 
 | 9915 |     } | 
 | 9916 |  | 
 | 9917 |     // Suppress assigning zero-width bitfields. | 
| Richard Smith | a6b8b2c | 2011-10-10 18:28:20 +0000 | [diff] [blame] | 9918 |     if (Field->isBitField() && Field->getBitWidthValue(Context) == 0) | 
 | 9919 |       continue; | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9920 |      | 
 | 9921 |     QualType FieldType = Field->getType().getNonReferenceType(); | 
 | 9922 |     if (FieldType->isIncompleteArrayType()) { | 
 | 9923 |       assert(ClassDecl->hasFlexibleArrayMember() &&  | 
 | 9924 |              "Incomplete array type is not valid"); | 
 | 9925 |       continue; | 
 | 9926 |     } | 
 | 9927 |      | 
 | 9928 |     // Build references to the field in the object we're copying from and to. | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9929 |     LookupResult MemberLookup(*this, Field->getDeclName(), Loc, | 
 | 9930 |                               LookupMemberName); | 
| David Blaikie | 581deb3 | 2012-06-06 20:45:41 +0000 | [diff] [blame] | 9931 |     MemberLookup.addDecl(*Field); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9932 |     MemberLookup.resolveKind(); | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9933 |     MemberBuilder From(MoveOther, OtherRefType, | 
 | 9934 |                        /*IsArrow=*/false, MemberLookup); | 
 | 9935 |     MemberBuilder To(This, getCurrentThisType(), | 
 | 9936 |                      /*IsArrow=*/true, MemberLookup); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9937 |  | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9938 |     assert(!From.build(*this, Loc)->isLValue() && // could be xvalue or prvalue | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9939 |         "Member reference with rvalue base must be rvalue except for reference " | 
 | 9940 |         "members, which aren't allowed for move assignment."); | 
 | 9941 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9942 |     // Build the move of this field. | 
| Richard Smith | 8c88953 | 2012-11-14 00:50:40 +0000 | [diff] [blame] | 9943 |     StmtResult Move = buildSingleCopyAssign(*this, Loc, FieldType, | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9944 |                                             To, From, | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9945 |                                             /*CopyingBaseSubobject=*/false, | 
 | 9946 |                                             /*Copying=*/false); | 
 | 9947 |     if (Move.isInvalid()) { | 
 | 9948 |       Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9949 |         << CXXMoveAssignment << Context.getTagDeclType(ClassDecl); | 
 | 9950 |       MoveAssignOperator->setInvalidDecl(); | 
 | 9951 |       return; | 
 | 9952 |     } | 
| Richard Smith | e7ce709 | 2012-11-12 23:33:00 +0000 | [diff] [blame] | 9953 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9954 |     // Success! Record the copy. | 
 | 9955 |     Statements.push_back(Move.takeAs<Stmt>()); | 
 | 9956 |   } | 
 | 9957 |  | 
 | 9958 |   if (!Invalid) { | 
 | 9959 |     // Add a "return *this;" | 
| Pavel Labath | 66ea35d | 2013-08-30 08:52:28 +0000 | [diff] [blame] | 9960 |     ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc)); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9961 |      | 
 | 9962 |     StmtResult Return = ActOnReturnStmt(Loc, ThisObj.get()); | 
 | 9963 |     if (Return.isInvalid()) | 
 | 9964 |       Invalid = true; | 
 | 9965 |     else { | 
 | 9966 |       Statements.push_back(Return.takeAs<Stmt>()); | 
 | 9967 |  | 
 | 9968 |       if (Trap.hasErrorOccurred()) { | 
 | 9969 |         Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 9970 |           << CXXMoveAssignment << Context.getTagDeclType(ClassDecl); | 
 | 9971 |         Invalid = true; | 
 | 9972 |       } | 
 | 9973 |     } | 
 | 9974 |   } | 
 | 9975 |  | 
 | 9976 |   if (Invalid) { | 
 | 9977 |     MoveAssignOperator->setInvalidDecl(); | 
 | 9978 |     return; | 
 | 9979 |   } | 
| Dmitri Gribenko | 625bb56 | 2012-02-14 22:14:32 +0000 | [diff] [blame] | 9980 |  | 
 | 9981 |   StmtResult Body; | 
 | 9982 |   { | 
 | 9983 |     CompoundScopeRAII CompoundScope(*this); | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 9984 |     Body = ActOnCompoundStmt(Loc, Loc, Statements, | 
| Dmitri Gribenko | 625bb56 | 2012-02-14 22:14:32 +0000 | [diff] [blame] | 9985 |                              /*isStmtExpr=*/false); | 
 | 9986 |     assert(!Body.isInvalid() && "Compound statement creation cannot fail"); | 
 | 9987 |   } | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 9988 |   MoveAssignOperator->setBody(Body.takeAs<Stmt>()); | 
 | 9989 |  | 
 | 9990 |   if (ASTMutationListener *L = getASTMutationListener()) { | 
 | 9991 |     L->CompletedImplicitDefinition(MoveAssignOperator); | 
 | 9992 |   } | 
 | 9993 | } | 
 | 9994 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 9995 | Sema::ImplicitExceptionSpecification | 
 | 9996 | Sema::ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD) { | 
 | 9997 |   CXXRecordDecl *ClassDecl = MD->getParent(); | 
 | 9998 |  | 
 | 9999 |   ImplicitExceptionSpecification ExceptSpec(*this); | 
 | 10000 |   if (ClassDecl->isInvalidDecl()) | 
 | 10001 |     return ExceptSpec; | 
 | 10002 |  | 
 | 10003 |   const FunctionProtoType *T = MD->getType()->castAs<FunctionProtoType>(); | 
 | 10004 |   assert(T->getNumArgs() >= 1 && "not a copy ctor"); | 
 | 10005 |   unsigned Quals = T->getArgType(0).getNonReferenceType().getCVRQualifiers(); | 
 | 10006 |  | 
| Douglas Gregor | 0d405db | 2010-07-01 20:59:04 +0000 | [diff] [blame] | 10007 |   // C++ [except.spec]p14: | 
 | 10008 |   //   An implicitly declared special member function (Clause 12) shall have an  | 
 | 10009 |   //   exception-specification. [...] | 
| Douglas Gregor | 0d405db | 2010-07-01 20:59:04 +0000 | [diff] [blame] | 10010 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), | 
 | 10011 |                                        BaseEnd = ClassDecl->bases_end(); | 
 | 10012 |        Base != BaseEnd;  | 
 | 10013 |        ++Base) { | 
 | 10014 |     // Virtual bases are handled below. | 
 | 10015 |     if (Base->isVirtual()) | 
 | 10016 |       continue; | 
 | 10017 |      | 
| Douglas Gregor | 2258431 | 2010-07-02 23:41:54 +0000 | [diff] [blame] | 10018 |     CXXRecordDecl *BaseClassDecl | 
| Douglas Gregor | 0d405db | 2010-07-01 20:59:04 +0000 | [diff] [blame] | 10019 |       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); | 
| Sean Hunt | c530d17 | 2011-06-10 04:44:37 +0000 | [diff] [blame] | 10020 |     if (CXXConstructorDecl *CopyConstructor = | 
| Sean Hunt | 661c67a | 2011-06-21 23:42:56 +0000 | [diff] [blame] | 10021 |           LookupCopyingConstructor(BaseClassDecl, Quals)) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 10022 |       ExceptSpec.CalledDecl(Base->getLocStart(), CopyConstructor); | 
| Douglas Gregor | 0d405db | 2010-07-01 20:59:04 +0000 | [diff] [blame] | 10023 |   } | 
 | 10024 |   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), | 
 | 10025 |                                        BaseEnd = ClassDecl->vbases_end(); | 
 | 10026 |        Base != BaseEnd;  | 
 | 10027 |        ++Base) { | 
| Douglas Gregor | 2258431 | 2010-07-02 23:41:54 +0000 | [diff] [blame] | 10028 |     CXXRecordDecl *BaseClassDecl | 
| Douglas Gregor | 0d405db | 2010-07-01 20:59:04 +0000 | [diff] [blame] | 10029 |       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); | 
| Sean Hunt | c530d17 | 2011-06-10 04:44:37 +0000 | [diff] [blame] | 10030 |     if (CXXConstructorDecl *CopyConstructor = | 
| Sean Hunt | 661c67a | 2011-06-21 23:42:56 +0000 | [diff] [blame] | 10031 |           LookupCopyingConstructor(BaseClassDecl, Quals)) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 10032 |       ExceptSpec.CalledDecl(Base->getLocStart(), CopyConstructor); | 
| Douglas Gregor | 0d405db | 2010-07-01 20:59:04 +0000 | [diff] [blame] | 10033 |   } | 
 | 10034 |   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), | 
 | 10035 |                                   FieldEnd = ClassDecl->field_end(); | 
 | 10036 |        Field != FieldEnd; | 
 | 10037 |        ++Field) { | 
| David Blaikie | 262bc18 | 2012-04-30 02:36:29 +0000 | [diff] [blame] | 10038 |     QualType FieldType = Context.getBaseElementType(Field->getType()); | 
| Sean Hunt | c530d17 | 2011-06-10 04:44:37 +0000 | [diff] [blame] | 10039 |     if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) { | 
 | 10040 |       if (CXXConstructorDecl *CopyConstructor = | 
| Richard Smith | 6a06e5f | 2012-07-18 03:36:00 +0000 | [diff] [blame] | 10041 |               LookupCopyingConstructor(FieldClassDecl, | 
 | 10042 |                                        Quals | FieldType.getCVRQualifiers())) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 10043 |       ExceptSpec.CalledDecl(Field->getLocation(), CopyConstructor); | 
| Douglas Gregor | 0d405db | 2010-07-01 20:59:04 +0000 | [diff] [blame] | 10044 |     } | 
 | 10045 |   } | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 10046 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10047 |   return ExceptSpec; | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 10048 | } | 
 | 10049 |  | 
 | 10050 | CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor( | 
 | 10051 |                                                     CXXRecordDecl *ClassDecl) { | 
 | 10052 |   // C++ [class.copy]p4: | 
 | 10053 |   //   If the class definition does not explicitly declare a copy | 
 | 10054 |   //   constructor, one is declared implicitly. | 
| Richard Smith | e5411b7 | 2012-12-01 02:35:44 +0000 | [diff] [blame] | 10055 |   assert(ClassDecl->needsImplicitCopyConstructor()); | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 10056 |  | 
| Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 10057 |   DeclaringSpecialMember DSM(*this, ClassDecl, CXXCopyConstructor); | 
 | 10058 |   if (DSM.isAlreadyBeingDeclared()) | 
 | 10059 |     return 0; | 
 | 10060 |  | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 10061 |   QualType ClassType = Context.getTypeDeclType(ClassDecl); | 
 | 10062 |   QualType ArgType = ClassType; | 
| Richard Smith | acf796b | 2012-11-28 06:23:12 +0000 | [diff] [blame] | 10063 |   bool Const = ClassDecl->implicitCopyConstructorHasConstParam(); | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 10064 |   if (Const) | 
 | 10065 |     ArgType = ArgType.withConst(); | 
 | 10066 |   ArgType = Context.getLValueReferenceType(ArgType); | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 10067 |  | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 10068 |   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl, | 
 | 10069 |                                                      CXXCopyConstructor, | 
 | 10070 |                                                      Const); | 
 | 10071 |  | 
| Douglas Gregor | 4a0c26f | 2010-07-01 17:57:27 +0000 | [diff] [blame] | 10072 |   DeclarationName Name | 
 | 10073 |     = Context.DeclarationNames.getCXXConstructorName( | 
 | 10074 |                                            Context.getCanonicalType(ClassType)); | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 10075 |   SourceLocation ClassLoc = ClassDecl->getLocation(); | 
 | 10076 |   DeclarationNameInfo NameInfo(Name, ClassLoc); | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 10077 |  | 
 | 10078 |   //   An implicitly-declared copy constructor is an inline public | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 10079 |   //   member of its class. | 
 | 10080 |   CXXConstructorDecl *CopyConstructor = CXXConstructorDecl::Create( | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10081 |       Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/0, | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 10082 |       /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true, | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 10083 |       Constexpr); | 
| Douglas Gregor | 4a0c26f | 2010-07-01 17:57:27 +0000 | [diff] [blame] | 10084 |   CopyConstructor->setAccess(AS_public); | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 10085 |   CopyConstructor->setDefaulted(); | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 10086 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10087 |   // Build an exception specification pointing back at this member. | 
| Reid Kleckner | ef07203 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 10088 |   FunctionProtoType::ExtProtoInfo EPI = | 
 | 10089 |       getImplicitMethodEPI(*this, CopyConstructor); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10090 |   CopyConstructor->setType( | 
| Jordan Rose | bea522f | 2013-03-08 21:51:21 +0000 | [diff] [blame] | 10091 |       Context.getFunctionType(Context.VoidTy, ArgType, EPI)); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10092 |  | 
| Douglas Gregor | 4a0c26f | 2010-07-01 17:57:27 +0000 | [diff] [blame] | 10093 |   // Add the parameter to the constructor. | 
 | 10094 |   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor, | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 10095 |                                                ClassLoc, ClassLoc, | 
| Douglas Gregor | 4a0c26f | 2010-07-01 17:57:27 +0000 | [diff] [blame] | 10096 |                                                /*IdentifierInfo=*/0, | 
 | 10097 |                                                ArgType, /*TInfo=*/0, | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 10098 |                                                SC_None, 0); | 
| David Blaikie | 4278c65 | 2011-09-21 18:16:56 +0000 | [diff] [blame] | 10099 |   CopyConstructor->setParams(FromParam); | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 10100 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 10101 |   CopyConstructor->setTrivial( | 
 | 10102 |     ClassDecl->needsOverloadResolutionForCopyConstructor() | 
 | 10103 |       ? SpecialMemberIsTrivial(CopyConstructor, CXXCopyConstructor) | 
 | 10104 |       : ClassDecl->hasTrivialCopyConstructor()); | 
| Sean Hunt | 71a682f | 2011-05-18 03:41:58 +0000 | [diff] [blame] | 10105 |  | 
| Nico Weber | afcc96a | 2012-01-23 03:19:29 +0000 | [diff] [blame] | 10106 |   // C++11 [class.copy]p8: | 
 | 10107 |   //   ... If the class definition does not explicitly declare a copy | 
 | 10108 |   //   constructor, there is no user-declared move constructor, and there is no | 
 | 10109 |   //   user-declared move assignment operator, a copy constructor is implicitly | 
 | 10110 |   //   declared as defaulted. | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 10111 |   if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) | 
| Richard Smith | 0ab5b4c | 2013-04-02 19:38:47 +0000 | [diff] [blame] | 10112 |     SetDeclDeleted(CopyConstructor, ClassLoc); | 
| Richard Smith | 6c4c36c | 2012-03-30 20:53:28 +0000 | [diff] [blame] | 10113 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 10114 |   // Note that we have declared this constructor. | 
 | 10115 |   ++ASTContext::NumImplicitCopyConstructorsDeclared; | 
 | 10116 |  | 
 | 10117 |   if (Scope *S = getScopeForContext(ClassDecl)) | 
 | 10118 |     PushOnScopeChains(CopyConstructor, S, false); | 
 | 10119 |   ClassDecl->addDecl(CopyConstructor); | 
 | 10120 |  | 
| Douglas Gregor | 4a0c26f | 2010-07-01 17:57:27 +0000 | [diff] [blame] | 10121 |   return CopyConstructor; | 
 | 10122 | } | 
 | 10123 |  | 
| Fariborz Jahanian | 485f087 | 2009-06-22 23:34:40 +0000 | [diff] [blame] | 10124 | void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 10125 |                                    CXXConstructorDecl *CopyConstructor) { | 
 | 10126 |   assert((CopyConstructor->isDefaulted() && | 
 | 10127 |           CopyConstructor->isCopyConstructor() && | 
| Richard Smith | 03f6878 | 2012-02-26 07:51:39 +0000 | [diff] [blame] | 10128 |           !CopyConstructor->doesThisDeclarationHaveABody() && | 
 | 10129 |           !CopyConstructor->isDeleted()) && | 
| Fariborz Jahanian | 485f087 | 2009-06-22 23:34:40 +0000 | [diff] [blame] | 10130 |          "DefineImplicitCopyConstructor - call it for implicit copy ctor"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10131 |  | 
| Anders Carlsson | 63010a7 | 2010-04-23 16:24:12 +0000 | [diff] [blame] | 10132 |   CXXRecordDecl *ClassDecl = CopyConstructor->getParent(); | 
| Fariborz Jahanian | 485f087 | 2009-06-22 23:34:40 +0000 | [diff] [blame] | 10133 |   assert(ClassDecl && "DefineImplicitCopyConstructor - invalid constructor"); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 10134 |  | 
| Richard Smith | 36155c1 | 2013-06-13 03:23:42 +0000 | [diff] [blame] | 10135 |   // C++11 [class.copy]p7: | 
| Benjamin Kramer | e575359 | 2013-09-09 14:48:42 +0000 | [diff] [blame] | 10136 |   //   The [definition of an implicitly declared copy constructor] is | 
| Richard Smith | 36155c1 | 2013-06-13 03:23:42 +0000 | [diff] [blame] | 10137 |   //   deprecated if the class has a user-declared copy assignment operator | 
 | 10138 |   //   or a user-declared destructor. | 
 | 10139 |   if (getLangOpts().CPlusPlus11 && CopyConstructor->isImplicit()) | 
 | 10140 |     diagnoseDeprecatedCopyOperation(*this, CopyConstructor, CurrentLocation); | 
 | 10141 |  | 
| Eli Friedman | 9a14db3 | 2012-10-18 20:14:08 +0000 | [diff] [blame] | 10142 |   SynthesizedFunctionScope Scope(*this, CopyConstructor); | 
| Argyrios Kyrtzidis | 9c4eb1f | 2010-11-19 00:19:12 +0000 | [diff] [blame] | 10143 |   DiagnosticErrorTrap Trap(Diags); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 10144 |  | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 10145 |   if (SetCtorInitializers(CopyConstructor, /*AnyErrors=*/false) || | 
| Douglas Gregor | c63d2c8 | 2010-05-12 16:39:35 +0000 | [diff] [blame] | 10146 |       Trap.hasErrorOccurred()) { | 
| Anders Carlsson | 59b7f15 | 2010-05-01 16:39:01 +0000 | [diff] [blame] | 10147 |     Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 10148 |       << CXXCopyConstructor << Context.getTagDeclType(ClassDecl); | 
| Anders Carlsson | 59b7f15 | 2010-05-01 16:39:01 +0000 | [diff] [blame] | 10149 |     CopyConstructor->setInvalidDecl(); | 
| Douglas Gregor | fb8cc25 | 2010-05-05 05:51:00 +0000 | [diff] [blame] | 10150 |   }  else { | 
| Dmitri Gribenko | 625bb56 | 2012-02-14 22:14:32 +0000 | [diff] [blame] | 10151 |     Sema::CompoundScopeRAII CompoundScope(*this); | 
| Robert Wilhelm | c895f4d | 2013-08-19 20:51:20 +0000 | [diff] [blame] | 10152 |     CopyConstructor->setBody(ActOnCompoundStmt( | 
 | 10153 |         CopyConstructor->getLocation(), CopyConstructor->getLocation(), None, | 
 | 10154 |         /*isStmtExpr=*/ false).takeAs<Stmt>()); | 
| Anders Carlsson | 8e142cc | 2010-04-25 00:52:09 +0000 | [diff] [blame] | 10155 |   } | 
| Robert Wilhelm | c895f4d | 2013-08-19 20:51:20 +0000 | [diff] [blame] | 10156 |  | 
| Eli Friedman | 86164e8 | 2013-09-05 00:02:25 +0000 | [diff] [blame] | 10157 |   CopyConstructor->markUsed(Context); | 
| Sebastian Redl | 58a2cd8 | 2011-04-24 16:28:06 +0000 | [diff] [blame] | 10158 |   if (ASTMutationListener *L = getASTMutationListener()) { | 
 | 10159 |     L->CompletedImplicitDefinition(CopyConstructor); | 
 | 10160 |   } | 
| Fariborz Jahanian | 485f087 | 2009-06-22 23:34:40 +0000 | [diff] [blame] | 10161 | } | 
 | 10162 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10163 | Sema::ImplicitExceptionSpecification | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10164 | Sema::ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD) { | 
 | 10165 |   CXXRecordDecl *ClassDecl = MD->getParent(); | 
 | 10166 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10167 |   // C++ [except.spec]p14: | 
 | 10168 |   //   An implicitly declared special member function (Clause 12) shall have an  | 
 | 10169 |   //   exception-specification. [...] | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 10170 |   ImplicitExceptionSpecification ExceptSpec(*this); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10171 |   if (ClassDecl->isInvalidDecl()) | 
 | 10172 |     return ExceptSpec; | 
 | 10173 |  | 
 | 10174 |   // Direct base-class constructors. | 
 | 10175 |   for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(), | 
 | 10176 |                                        BEnd = ClassDecl->bases_end(); | 
 | 10177 |        B != BEnd; ++B) { | 
 | 10178 |     if (B->isVirtual()) // Handled below. | 
 | 10179 |       continue; | 
 | 10180 |      | 
 | 10181 |     if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) { | 
 | 10182 |       CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); | 
| Richard Smith | 6a06e5f | 2012-07-18 03:36:00 +0000 | [diff] [blame] | 10183 |       CXXConstructorDecl *Constructor = | 
 | 10184 |           LookupMovingConstructor(BaseClassDecl, 0); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10185 |       // If this is a deleted function, add it anyway. This might be conformant | 
 | 10186 |       // with the standard. This might not. I'm not sure. It might not matter. | 
 | 10187 |       if (Constructor) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 10188 |         ExceptSpec.CalledDecl(B->getLocStart(), Constructor); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10189 |     } | 
 | 10190 |   } | 
 | 10191 |  | 
 | 10192 |   // Virtual base-class constructors. | 
 | 10193 |   for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(), | 
 | 10194 |                                        BEnd = ClassDecl->vbases_end(); | 
 | 10195 |        B != BEnd; ++B) { | 
 | 10196 |     if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) { | 
 | 10197 |       CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl()); | 
| Richard Smith | 6a06e5f | 2012-07-18 03:36:00 +0000 | [diff] [blame] | 10198 |       CXXConstructorDecl *Constructor = | 
 | 10199 |           LookupMovingConstructor(BaseClassDecl, 0); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10200 |       // If this is a deleted function, add it anyway. This might be conformant | 
 | 10201 |       // with the standard. This might not. I'm not sure. It might not matter. | 
 | 10202 |       if (Constructor) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 10203 |         ExceptSpec.CalledDecl(B->getLocStart(), Constructor); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10204 |     } | 
 | 10205 |   } | 
 | 10206 |  | 
 | 10207 |   // Field constructors. | 
 | 10208 |   for (RecordDecl::field_iterator F = ClassDecl->field_begin(), | 
 | 10209 |                                FEnd = ClassDecl->field_end(); | 
 | 10210 |        F != FEnd; ++F) { | 
| Richard Smith | 6a06e5f | 2012-07-18 03:36:00 +0000 | [diff] [blame] | 10211 |     QualType FieldType = Context.getBaseElementType(F->getType()); | 
 | 10212 |     if (CXXRecordDecl *FieldRecDecl = FieldType->getAsCXXRecordDecl()) { | 
 | 10213 |       CXXConstructorDecl *Constructor = | 
 | 10214 |           LookupMovingConstructor(FieldRecDecl, FieldType.getCVRQualifiers()); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10215 |       // If this is a deleted function, add it anyway. This might be conformant | 
 | 10216 |       // with the standard. This might not. I'm not sure. It might not matter. | 
 | 10217 |       // In particular, the problem is that this function never gets called. It | 
 | 10218 |       // might just be ill-formed because this function attempts to refer to | 
 | 10219 |       // a deleted function here. | 
 | 10220 |       if (Constructor) | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 10221 |         ExceptSpec.CalledDecl(F->getLocation(), Constructor); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10222 |     } | 
 | 10223 |   } | 
 | 10224 |  | 
 | 10225 |   return ExceptSpec; | 
 | 10226 | } | 
 | 10227 |  | 
 | 10228 | CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor( | 
 | 10229 |                                                     CXXRecordDecl *ClassDecl) { | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 10230 |   // C++11 [class.copy]p9: | 
 | 10231 |   //   If the definition of a class X does not explicitly declare a move | 
 | 10232 |   //   constructor, one will be implicitly declared as defaulted if and only if: | 
 | 10233 |   // | 
 | 10234 |   //   - [first 4 bullets] | 
 | 10235 |   assert(ClassDecl->needsImplicitMoveConstructor()); | 
 | 10236 |  | 
| Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 10237 |   DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveConstructor); | 
 | 10238 |   if (DSM.isAlreadyBeingDeclared()) | 
 | 10239 |     return 0; | 
 | 10240 |  | 
| Richard Smith | 1c931be | 2012-04-02 18:40:40 +0000 | [diff] [blame] | 10241 |   // [Checked after we build the declaration] | 
 | 10242 |   //   - the move assignment operator would not be implicitly defined as | 
 | 10243 |   //     deleted, | 
 | 10244 |  | 
 | 10245 |   // [DR1402]: | 
 | 10246 |   //   - each of X's non-static data members and direct or virtual base classes | 
 | 10247 |   //     has a type that either has a move constructor or is trivially copyable. | 
 | 10248 |   if (!subobjectsHaveMoveOrTrivialCopy(*this, ClassDecl, /*Constructor*/true)) { | 
 | 10249 |     ClassDecl->setFailedImplicitMoveConstructor(); | 
 | 10250 |     return 0; | 
 | 10251 |   } | 
 | 10252 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10253 |   QualType ClassType = Context.getTypeDeclType(ClassDecl); | 
 | 10254 |   QualType ArgType = Context.getRValueReferenceType(ClassType); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10255 |  | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 10256 |   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl, | 
 | 10257 |                                                      CXXMoveConstructor, | 
 | 10258 |                                                      false); | 
 | 10259 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10260 |   DeclarationName Name | 
 | 10261 |     = Context.DeclarationNames.getCXXConstructorName( | 
 | 10262 |                                            Context.getCanonicalType(ClassType)); | 
 | 10263 |   SourceLocation ClassLoc = ClassDecl->getLocation(); | 
 | 10264 |   DeclarationNameInfo NameInfo(Name, ClassLoc); | 
 | 10265 |  | 
| Richard Smith | a8942d7 | 2013-05-07 03:19:20 +0000 | [diff] [blame] | 10266 |   // C++11 [class.copy]p11: | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10267 |   //   An implicitly-declared copy/move constructor is an inline public | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 10268 |   //   member of its class. | 
 | 10269 |   CXXConstructorDecl *MoveConstructor = CXXConstructorDecl::Create( | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10270 |       Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/0, | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 10271 |       /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true, | 
| Richard Smith | 7756afa | 2012-06-10 05:43:50 +0000 | [diff] [blame] | 10272 |       Constexpr); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10273 |   MoveConstructor->setAccess(AS_public); | 
 | 10274 |   MoveConstructor->setDefaulted(); | 
| Richard Smith | 6180245 | 2011-12-22 02:22:31 +0000 | [diff] [blame] | 10275 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10276 |   // Build an exception specification pointing back at this member. | 
| Reid Kleckner | ef07203 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 10277 |   FunctionProtoType::ExtProtoInfo EPI = | 
 | 10278 |       getImplicitMethodEPI(*this, MoveConstructor); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10279 |   MoveConstructor->setType( | 
| Jordan Rose | bea522f | 2013-03-08 21:51:21 +0000 | [diff] [blame] | 10280 |       Context.getFunctionType(Context.VoidTy, ArgType, EPI)); | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 10281 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10282 |   // Add the parameter to the constructor. | 
 | 10283 |   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveConstructor, | 
 | 10284 |                                                ClassLoc, ClassLoc, | 
 | 10285 |                                                /*IdentifierInfo=*/0, | 
 | 10286 |                                                ArgType, /*TInfo=*/0, | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10287 |                                                SC_None, 0); | 
| David Blaikie | 4278c65 | 2011-09-21 18:16:56 +0000 | [diff] [blame] | 10288 |   MoveConstructor->setParams(FromParam); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10289 |  | 
| Richard Smith | bc2a35d | 2012-12-08 08:32:28 +0000 | [diff] [blame] | 10290 |   MoveConstructor->setTrivial( | 
 | 10291 |     ClassDecl->needsOverloadResolutionForMoveConstructor() | 
 | 10292 |       ? SpecialMemberIsTrivial(MoveConstructor, CXXMoveConstructor) | 
 | 10293 |       : ClassDecl->hasTrivialMoveConstructor()); | 
 | 10294 |  | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10295 |   // C++0x [class.copy]p9: | 
 | 10296 |   //   If the definition of a class X does not explicitly declare a move | 
 | 10297 |   //   constructor, one will be implicitly declared as defaulted if and only if: | 
 | 10298 |   //   [...] | 
 | 10299 |   //   - the move constructor would not be implicitly defined as deleted. | 
| Sean Hunt | 769bb2d | 2011-10-11 06:43:29 +0000 | [diff] [blame] | 10300 |   if (ShouldDeleteSpecialMember(MoveConstructor, CXXMoveConstructor)) { | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10301 |     // Cache this result so that we don't try to generate this over and over | 
 | 10302 |     // on every lookup, leaking memory and wasting time. | 
 | 10303 |     ClassDecl->setFailedImplicitMoveConstructor(); | 
 | 10304 |     return 0; | 
 | 10305 |   } | 
 | 10306 |  | 
 | 10307 |   // Note that we have declared this constructor. | 
 | 10308 |   ++ASTContext::NumImplicitMoveConstructorsDeclared; | 
 | 10309 |  | 
 | 10310 |   if (Scope *S = getScopeForContext(ClassDecl)) | 
 | 10311 |     PushOnScopeChains(MoveConstructor, S, false); | 
 | 10312 |   ClassDecl->addDecl(MoveConstructor); | 
 | 10313 |  | 
 | 10314 |   return MoveConstructor; | 
 | 10315 | } | 
 | 10316 |  | 
 | 10317 | void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation, | 
 | 10318 |                                    CXXConstructorDecl *MoveConstructor) { | 
 | 10319 |   assert((MoveConstructor->isDefaulted() && | 
 | 10320 |           MoveConstructor->isMoveConstructor() && | 
| Richard Smith | 03f6878 | 2012-02-26 07:51:39 +0000 | [diff] [blame] | 10321 |           !MoveConstructor->doesThisDeclarationHaveABody() && | 
 | 10322 |           !MoveConstructor->isDeleted()) && | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10323 |          "DefineImplicitMoveConstructor - call it for implicit move ctor"); | 
 | 10324 |  | 
 | 10325 |   CXXRecordDecl *ClassDecl = MoveConstructor->getParent(); | 
 | 10326 |   assert(ClassDecl && "DefineImplicitMoveConstructor - invalid constructor"); | 
 | 10327 |  | 
| Eli Friedman | 9a14db3 | 2012-10-18 20:14:08 +0000 | [diff] [blame] | 10328 |   SynthesizedFunctionScope Scope(*this, MoveConstructor); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10329 |   DiagnosticErrorTrap Trap(Diags); | 
 | 10330 |  | 
| David Blaikie | 93c8617 | 2013-01-17 05:26:25 +0000 | [diff] [blame] | 10331 |   if (SetCtorInitializers(MoveConstructor, /*AnyErrors=*/false) || | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10332 |       Trap.hasErrorOccurred()) { | 
 | 10333 |     Diag(CurrentLocation, diag::note_member_synthesized_at)  | 
 | 10334 |       << CXXMoveConstructor << Context.getTagDeclType(ClassDecl); | 
 | 10335 |     MoveConstructor->setInvalidDecl(); | 
 | 10336 |   }  else { | 
| Dmitri Gribenko | 625bb56 | 2012-02-14 22:14:32 +0000 | [diff] [blame] | 10337 |     Sema::CompoundScopeRAII CompoundScope(*this); | 
| Robert Wilhelm | c895f4d | 2013-08-19 20:51:20 +0000 | [diff] [blame] | 10338 |     MoveConstructor->setBody(ActOnCompoundStmt( | 
 | 10339 |         MoveConstructor->getLocation(), MoveConstructor->getLocation(), None, | 
 | 10340 |         /*isStmtExpr=*/ false).takeAs<Stmt>()); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10341 |   } | 
 | 10342 |  | 
| Eli Friedman | 86164e8 | 2013-09-05 00:02:25 +0000 | [diff] [blame] | 10343 |   MoveConstructor->markUsed(Context); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 10344 |  | 
 | 10345 |   if (ASTMutationListener *L = getASTMutationListener()) { | 
 | 10346 |     L->CompletedImplicitDefinition(MoveConstructor); | 
 | 10347 |   } | 
 | 10348 | } | 
 | 10349 |  | 
| Douglas Gregor | e4e68d4 | 2012-02-15 19:33:52 +0000 | [diff] [blame] | 10350 | bool Sema::isImplicitlyDeleted(FunctionDecl *FD) { | 
| Eli Friedman | c4ef948 | 2013-07-18 23:29:14 +0000 | [diff] [blame] | 10351 |   return FD->isDeleted() && FD->isDefaulted() && isa<CXXMethodDecl>(FD); | 
| Douglas Gregor | e4e68d4 | 2012-02-15 19:33:52 +0000 | [diff] [blame] | 10352 | } | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10353 |  | 
 | 10354 | void Sema::DefineImplicitLambdaToFunctionPointerConversion( | 
| Faisal Vali | d6992ab | 2013-09-29 08:45:24 +0000 | [diff] [blame] | 10355 |                             SourceLocation CurrentLocation, | 
 | 10356 |                             CXXConversionDecl *Conv) { | 
 | 10357 |   CXXRecordDecl *Lambda = Conv->getParent(); | 
 | 10358 |   CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator(); | 
 | 10359 |   // If we are defining a specialization of a conversion to function-ptr | 
 | 10360 |   // cache the deduced template arguments for this specialization | 
 | 10361 |   // so that we can use them to retrieve the corresponding call-operator | 
 | 10362 |   // and static-invoker.  | 
 | 10363 |   const TemplateArgumentList *DeducedTemplateArgs = 0; | 
 | 10364 |     | 
| Douglas Gregor | 27dd7d9 | 2012-02-17 03:02:34 +0000 | [diff] [blame] | 10365 |    | 
| Faisal Vali | d6992ab | 2013-09-29 08:45:24 +0000 | [diff] [blame] | 10366 |   // Retrieve the corresponding call-operator specialization. | 
 | 10367 |   if (Lambda->isGenericLambda()) { | 
 | 10368 |     assert(Conv->isFunctionTemplateSpecialization()); | 
 | 10369 |     FunctionTemplateDecl *CallOpTemplate =  | 
 | 10370 |         CallOp->getDescribedFunctionTemplate(); | 
 | 10371 |     DeducedTemplateArgs = Conv->getTemplateSpecializationArgs(); | 
 | 10372 |     void *InsertPos = 0; | 
 | 10373 |     FunctionDecl *CallOpSpec = CallOpTemplate->findSpecialization( | 
 | 10374 |                                                 DeducedTemplateArgs->data(),  | 
 | 10375 |                                                 DeducedTemplateArgs->size(),  | 
 | 10376 |                                                 InsertPos); | 
 | 10377 |     assert(CallOpSpec &&  | 
 | 10378 |           "Conversion operator must have a corresponding call operator"); | 
 | 10379 |     CallOp = cast<CXXMethodDecl>(CallOpSpec); | 
 | 10380 |   } | 
 | 10381 |   // Mark the call operator referenced (and add to pending instantiations | 
 | 10382 |   // if necessary). | 
 | 10383 |   // For both the conversion and static-invoker template specializations | 
 | 10384 |   // we construct their body's in this function, so no need to add them | 
 | 10385 |   // to the PendingInstantiations. | 
 | 10386 |   MarkFunctionReferenced(CurrentLocation, CallOp); | 
 | 10387 |  | 
| Eli Friedman | 9a14db3 | 2012-10-18 20:14:08 +0000 | [diff] [blame] | 10388 |   SynthesizedFunctionScope Scope(*this, Conv); | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10389 |   DiagnosticErrorTrap Trap(Diags); | 
| Faisal Vali | d6992ab | 2013-09-29 08:45:24 +0000 | [diff] [blame] | 10390 |     | 
 | 10391 |   // Retreive the static invoker... | 
 | 10392 |   CXXMethodDecl *Invoker = Lambda->getLambdaStaticInvoker(); | 
 | 10393 |   // ... and get the corresponding specialization for a generic lambda. | 
 | 10394 |   if (Lambda->isGenericLambda()) { | 
 | 10395 |     assert(DeducedTemplateArgs &&  | 
 | 10396 |       "Must have deduced template arguments from Conversion Operator"); | 
 | 10397 |     FunctionTemplateDecl *InvokeTemplate =  | 
 | 10398 |                           Invoker->getDescribedFunctionTemplate(); | 
 | 10399 |     void *InsertPos = 0; | 
 | 10400 |     FunctionDecl *InvokeSpec = InvokeTemplate->findSpecialization( | 
 | 10401 |                                                 DeducedTemplateArgs->data(),  | 
 | 10402 |                                                 DeducedTemplateArgs->size(),  | 
 | 10403 |                                                 InsertPos); | 
 | 10404 |     assert(InvokeSpec &&  | 
 | 10405 |       "Must have a corresponding static invoker specialization"); | 
 | 10406 |     Invoker = cast<CXXMethodDecl>(InvokeSpec); | 
 | 10407 |   } | 
 | 10408 |   // Construct the body of the conversion function { return __invoke; }. | 
 | 10409 |   Expr *FunctionRef = BuildDeclRefExpr(Invoker, Invoker->getType(), | 
 | 10410 |                                         VK_LValue, Conv->getLocation()).take(); | 
 | 10411 |    assert(FunctionRef && "Can't refer to __invoke function?"); | 
 | 10412 |    Stmt *Return = ActOnReturnStmt(Conv->getLocation(), FunctionRef).take(); | 
 | 10413 |    Conv->setBody(new (Context) CompoundStmt(Context, Return, | 
 | 10414 |                                             Conv->getLocation(), | 
 | 10415 |                                             Conv->getLocation())); | 
 | 10416 |  | 
 | 10417 |   Conv->markUsed(Context); | 
 | 10418 |   Conv->setReferenced(); | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10419 |    | 
| Faisal Vali | d6992ab | 2013-09-29 08:45:24 +0000 | [diff] [blame] | 10420 |   // Fill in the __invoke function with a dummy implementation. IR generation | 
 | 10421 |   // will fill in the actual details. | 
 | 10422 |   Invoker->markUsed(Context); | 
 | 10423 |   Invoker->setReferenced(); | 
 | 10424 |   Invoker->setBody(new (Context) CompoundStmt(Conv->getLocation())); | 
 | 10425 |     | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10426 |   if (ASTMutationListener *L = getASTMutationListener()) { | 
 | 10427 |     L->CompletedImplicitDefinition(Conv); | 
| Faisal Vali | d6992ab | 2013-09-29 08:45:24 +0000 | [diff] [blame] | 10428 |     L->CompletedImplicitDefinition(Invoker); | 
 | 10429 |    } | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10430 | } | 
 | 10431 |  | 
| Faisal Vali | d6992ab | 2013-09-29 08:45:24 +0000 | [diff] [blame] | 10432 |  | 
 | 10433 |  | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10434 | void Sema::DefineImplicitLambdaToBlockPointerConversion( | 
 | 10435 |        SourceLocation CurrentLocation, | 
 | 10436 |        CXXConversionDecl *Conv)  | 
 | 10437 | { | 
| Faisal Vali | 56fe35b | 2013-09-29 17:08:32 +0000 | [diff] [blame] | 10438 |   assert(!Conv->getParent()->isGenericLambda()); | 
| Faisal Vali | d6992ab | 2013-09-29 08:45:24 +0000 | [diff] [blame] | 10439 |  | 
| Eli Friedman | 86164e8 | 2013-09-05 00:02:25 +0000 | [diff] [blame] | 10440 |   Conv->markUsed(Context); | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10441 |    | 
| Eli Friedman | 9a14db3 | 2012-10-18 20:14:08 +0000 | [diff] [blame] | 10442 |   SynthesizedFunctionScope Scope(*this, Conv); | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10443 |   DiagnosticErrorTrap Trap(Diags); | 
 | 10444 |    | 
| Douglas Gregor | ac1303e | 2012-02-22 05:02:47 +0000 | [diff] [blame] | 10445 |   // Copy-initialize the lambda object as needed to capture it. | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10446 |   Expr *This = ActOnCXXThis(CurrentLocation).take(); | 
 | 10447 |   Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).take(); | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10448 |    | 
| Eli Friedman | 23f0267 | 2012-03-01 04:01:32 +0000 | [diff] [blame] | 10449 |   ExprResult BuildBlock = BuildBlockForLambdaConversion(CurrentLocation, | 
 | 10450 |                                                         Conv->getLocation(), | 
 | 10451 |                                                         Conv, DerefThis); | 
 | 10452 |  | 
 | 10453 |   // If we're not under ARC, make sure we still get the _Block_copy/autorelease | 
 | 10454 |   // behavior.  Note that only the general conversion function does this | 
 | 10455 |   // (since it's unusable otherwise); in the case where we inline the | 
 | 10456 |   // block literal, it has block literal lifetime semantics. | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 10457 |   if (!BuildBlock.isInvalid() && !getLangOpts().ObjCAutoRefCount) | 
| Eli Friedman | 23f0267 | 2012-03-01 04:01:32 +0000 | [diff] [blame] | 10458 |     BuildBlock = ImplicitCastExpr::Create(Context, BuildBlock.get()->getType(), | 
 | 10459 |                                           CK_CopyAndAutoreleaseBlockObject, | 
 | 10460 |                                           BuildBlock.get(), 0, VK_RValue); | 
 | 10461 |  | 
 | 10462 |   if (BuildBlock.isInvalid()) { | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10463 |     Diag(CurrentLocation, diag::note_lambda_to_block_conv); | 
| Douglas Gregor | ac1303e | 2012-02-22 05:02:47 +0000 | [diff] [blame] | 10464 |     Conv->setInvalidDecl(); | 
 | 10465 |     return; | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10466 |   } | 
| Douglas Gregor | ac1303e | 2012-02-22 05:02:47 +0000 | [diff] [blame] | 10467 |  | 
| Douglas Gregor | ac1303e | 2012-02-22 05:02:47 +0000 | [diff] [blame] | 10468 |   // Create the return statement that returns the block from the conversion | 
 | 10469 |   // function. | 
| Eli Friedman | 23f0267 | 2012-03-01 04:01:32 +0000 | [diff] [blame] | 10470 |   StmtResult Return = ActOnReturnStmt(Conv->getLocation(), BuildBlock.get()); | 
| Douglas Gregor | ac1303e | 2012-02-22 05:02:47 +0000 | [diff] [blame] | 10471 |   if (Return.isInvalid()) { | 
 | 10472 |     Diag(CurrentLocation, diag::note_lambda_to_block_conv); | 
 | 10473 |     Conv->setInvalidDecl(); | 
 | 10474 |     return; | 
 | 10475 |   } | 
 | 10476 |  | 
 | 10477 |   // Set the body of the conversion function. | 
 | 10478 |   Stmt *ReturnS = Return.take(); | 
| Nico Weber | d36aa35 | 2012-12-29 20:03:39 +0000 | [diff] [blame] | 10479 |   Conv->setBody(new (Context) CompoundStmt(Context, ReturnS, | 
| Douglas Gregor | ac1303e | 2012-02-22 05:02:47 +0000 | [diff] [blame] | 10480 |                                            Conv->getLocation(),  | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10481 |                                            Conv->getLocation())); | 
 | 10482 |    | 
| Douglas Gregor | ac1303e | 2012-02-22 05:02:47 +0000 | [diff] [blame] | 10483 |   // We're done; notify the mutation listener, if any. | 
| Douglas Gregor | f6e2e02 | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 10484 |   if (ASTMutationListener *L = getASTMutationListener()) { | 
 | 10485 |     L->CompletedImplicitDefinition(Conv); | 
 | 10486 |   } | 
 | 10487 | } | 
 | 10488 |  | 
| Douglas Gregor | f52757d | 2012-03-10 06:53:13 +0000 | [diff] [blame] | 10489 | /// \brief Determine whether the given list arguments contains exactly one  | 
 | 10490 | /// "real" (non-default) argument. | 
 | 10491 | static bool hasOneRealArgument(MultiExprArg Args) { | 
 | 10492 |   switch (Args.size()) { | 
 | 10493 |   case 0: | 
 | 10494 |     return false; | 
 | 10495 |      | 
 | 10496 |   default: | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 10497 |     if (!Args[1]->isDefaultArgument()) | 
| Douglas Gregor | f52757d | 2012-03-10 06:53:13 +0000 | [diff] [blame] | 10498 |       return false; | 
 | 10499 |      | 
 | 10500 |     // fall through | 
 | 10501 |   case 1: | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 10502 |     return !Args[0]->isDefaultArgument(); | 
| Douglas Gregor | f52757d | 2012-03-10 06:53:13 +0000 | [diff] [blame] | 10503 |   } | 
 | 10504 |    | 
 | 10505 |   return false; | 
 | 10506 | } | 
 | 10507 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 10508 | ExprResult | 
| Anders Carlsson | ec8e5ea | 2009-09-05 07:40:38 +0000 | [diff] [blame] | 10509 | Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10510 |                             CXXConstructorDecl *Constructor, | 
| Douglas Gregor | 16006c9 | 2009-12-16 18:50:27 +0000 | [diff] [blame] | 10511 |                             MultiExprArg ExprArgs, | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 10512 |                             bool HadMultipleCandidates, | 
| Richard Smith | c83c230 | 2012-12-19 01:39:02 +0000 | [diff] [blame] | 10513 |                             bool IsListInitialization, | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 10514 |                             bool RequiresZeroInit, | 
| Chandler Carruth | 428edaf | 2010-10-25 08:47:36 +0000 | [diff] [blame] | 10515 |                             unsigned ConstructKind, | 
 | 10516 |                             SourceRange ParenRange) { | 
| Anders Carlsson | 9abf2ae | 2009-08-16 05:13:48 +0000 | [diff] [blame] | 10517 |   bool Elidable = false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10518 |  | 
| Douglas Gregor | 2f59979 | 2010-04-02 18:24:57 +0000 | [diff] [blame] | 10519 |   // C++0x [class.copy]p34: | 
 | 10520 |   //   When certain criteria are met, an implementation is allowed to | 
 | 10521 |   //   omit the copy/move construction of a class object, even if the | 
 | 10522 |   //   copy/move constructor and/or destructor for the object have | 
 | 10523 |   //   side effects. [...] | 
 | 10524 |   //     - when a temporary class object that has not been bound to a | 
 | 10525 |   //       reference (12.2) would be copied/moved to a class object | 
 | 10526 |   //       with the same cv-unqualified type, the copy/move operation | 
 | 10527 |   //       can be omitted by constructing the temporary object | 
 | 10528 |   //       directly into the target of the omitted copy/move | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 10529 |   if (ConstructKind == CXXConstructExpr::CK_Complete && | 
| Douglas Gregor | f52757d | 2012-03-10 06:53:13 +0000 | [diff] [blame] | 10530 |       Constructor->isCopyOrMoveConstructor() && hasOneRealArgument(ExprArgs)) { | 
| Benjamin Kramer | 5354e77 | 2012-08-23 23:38:35 +0000 | [diff] [blame] | 10531 |     Expr *SubExpr = ExprArgs[0]; | 
| John McCall | 558d2ab | 2010-09-15 10:14:12 +0000 | [diff] [blame] | 10532 |     Elidable = SubExpr->isTemporaryObject(Context, Constructor->getParent()); | 
| Anders Carlsson | 9abf2ae | 2009-08-16 05:13:48 +0000 | [diff] [blame] | 10533 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10534 |  | 
 | 10535 |   return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor, | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 10536 |                                Elidable, ExprArgs, HadMultipleCandidates, | 
| Richard Smith | c83c230 | 2012-12-19 01:39:02 +0000 | [diff] [blame] | 10537 |                                IsListInitialization, RequiresZeroInit, | 
 | 10538 |                                ConstructKind, ParenRange); | 
| Anders Carlsson | 9abf2ae | 2009-08-16 05:13:48 +0000 | [diff] [blame] | 10539 | } | 
 | 10540 |  | 
| Fariborz Jahanian | b2c352e | 2009-08-05 17:03:54 +0000 | [diff] [blame] | 10541 | /// BuildCXXConstructExpr - Creates a complete call to a constructor, | 
 | 10542 | /// including handling of its default argument expressions. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 10543 | ExprResult | 
| Anders Carlsson | ec8e5ea | 2009-09-05 07:40:38 +0000 | [diff] [blame] | 10544 | Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, | 
 | 10545 |                             CXXConstructorDecl *Constructor, bool Elidable, | 
| Douglas Gregor | 16006c9 | 2009-12-16 18:50:27 +0000 | [diff] [blame] | 10546 |                             MultiExprArg ExprArgs, | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 10547 |                             bool HadMultipleCandidates, | 
| Richard Smith | c83c230 | 2012-12-19 01:39:02 +0000 | [diff] [blame] | 10548 |                             bool IsListInitialization, | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 10549 |                             bool RequiresZeroInit, | 
| Chandler Carruth | 428edaf | 2010-10-25 08:47:36 +0000 | [diff] [blame] | 10550 |                             unsigned ConstructKind, | 
 | 10551 |                             SourceRange ParenRange) { | 
| Eli Friedman | 5f2987c | 2012-02-02 03:46:19 +0000 | [diff] [blame] | 10552 |   MarkFunctionReferenced(ConstructLoc, Constructor); | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 10553 |   return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc, | 
| Benjamin Kramer | 3b6bef9 | 2012-08-24 11:54:20 +0000 | [diff] [blame] | 10554 |                                         Constructor, Elidable, ExprArgs, | 
| Richard Smith | c83c230 | 2012-12-19 01:39:02 +0000 | [diff] [blame] | 10555 |                                         HadMultipleCandidates, | 
 | 10556 |                                         IsListInitialization, RequiresZeroInit, | 
| Chandler Carruth | 428edaf | 2010-10-25 08:47:36 +0000 | [diff] [blame] | 10557 |               static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind), | 
 | 10558 |                                         ParenRange)); | 
| Fariborz Jahanian | b2c352e | 2009-08-05 17:03:54 +0000 | [diff] [blame] | 10559 | } | 
 | 10560 |  | 
| John McCall | 68c6c9a | 2010-02-02 09:10:11 +0000 | [diff] [blame] | 10561 | void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) { | 
| Chandler Carruth | 1d71cbf | 2011-03-27 21:26:48 +0000 | [diff] [blame] | 10562 |   if (VD->isInvalidDecl()) return; | 
 | 10563 |  | 
| John McCall | 68c6c9a | 2010-02-02 09:10:11 +0000 | [diff] [blame] | 10564 |   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Record->getDecl()); | 
| Chandler Carruth | 1d71cbf | 2011-03-27 21:26:48 +0000 | [diff] [blame] | 10565 |   if (ClassDecl->isInvalidDecl()) return; | 
| Richard Smith | 213d70b | 2012-02-18 04:13:32 +0000 | [diff] [blame] | 10566 |   if (ClassDecl->hasIrrelevantDestructor()) return; | 
| Chandler Carruth | 1d71cbf | 2011-03-27 21:26:48 +0000 | [diff] [blame] | 10567 |   if (ClassDecl->isDependentContext()) return; | 
| John McCall | 626e96e | 2010-08-01 20:20:59 +0000 | [diff] [blame] | 10568 |  | 
| Chandler Carruth | 1d71cbf | 2011-03-27 21:26:48 +0000 | [diff] [blame] | 10569 |   CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl); | 
| Eli Friedman | 5f2987c | 2012-02-02 03:46:19 +0000 | [diff] [blame] | 10570 |   MarkFunctionReferenced(VD->getLocation(), Destructor); | 
| Chandler Carruth | 1d71cbf | 2011-03-27 21:26:48 +0000 | [diff] [blame] | 10571 |   CheckDestructorAccess(VD->getLocation(), Destructor, | 
 | 10572 |                         PDiag(diag::err_access_dtor_var) | 
 | 10573 |                         << VD->getDeclName() | 
 | 10574 |                         << VD->getType()); | 
| Richard Smith | 213d70b | 2012-02-18 04:13:32 +0000 | [diff] [blame] | 10575 |   DiagnoseUseOfDecl(Destructor, VD->getLocation()); | 
| Anders Carlsson | 2b32dad | 2011-03-24 01:01:41 +0000 | [diff] [blame] | 10576 |  | 
| Chandler Carruth | 1d71cbf | 2011-03-27 21:26:48 +0000 | [diff] [blame] | 10577 |   if (!VD->hasGlobalStorage()) return; | 
 | 10578 |  | 
 | 10579 |   // Emit warning for non-trivial dtor in global scope (a real global, | 
 | 10580 |   // class-static, function-static). | 
 | 10581 |   Diag(VD->getLocation(), diag::warn_exit_time_destructor); | 
 | 10582 |  | 
 | 10583 |   // TODO: this should be re-enabled for static locals by !CXAAtExit | 
 | 10584 |   if (!VD->isStaticLocal()) | 
 | 10585 |     Diag(VD->getLocation(), diag::warn_global_destructor); | 
| Fariborz Jahanian | 8d2b356 | 2009-06-26 23:49:16 +0000 | [diff] [blame] | 10586 | } | 
 | 10587 |  | 
| Douglas Gregor | 39da0b8 | 2009-09-09 23:08:42 +0000 | [diff] [blame] | 10588 | /// \brief Given a constructor and the set of arguments provided for the | 
 | 10589 | /// constructor, convert the arguments and add any required default arguments | 
 | 10590 | /// to form a proper call to this constructor. | 
 | 10591 | /// | 
 | 10592 | /// \returns true if an error occurred, false otherwise. | 
 | 10593 | bool  | 
 | 10594 | Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, | 
 | 10595 |                               MultiExprArg ArgsPtr, | 
| Richard Smith | 831421f | 2012-06-25 20:30:08 +0000 | [diff] [blame] | 10596 |                               SourceLocation Loc, | 
| Benjamin Kramer | 4e28d9e | 2012-08-23 22:51:59 +0000 | [diff] [blame] | 10597 |                               SmallVectorImpl<Expr*> &ConvertedArgs, | 
| Richard Smith | a4dc51b | 2013-02-05 05:52:24 +0000 | [diff] [blame] | 10598 |                               bool AllowExplicit, | 
 | 10599 |                               bool IsListInitialization) { | 
| Douglas Gregor | 39da0b8 | 2009-09-09 23:08:42 +0000 | [diff] [blame] | 10600 |   // FIXME: This duplicates a lot of code from Sema::ConvertArgumentsForCall. | 
 | 10601 |   unsigned NumArgs = ArgsPtr.size(); | 
| Benjamin Kramer | 5354e77 | 2012-08-23 23:38:35 +0000 | [diff] [blame] | 10602 |   Expr **Args = ArgsPtr.data(); | 
| Douglas Gregor | 39da0b8 | 2009-09-09 23:08:42 +0000 | [diff] [blame] | 10603 |  | 
 | 10604 |   const FunctionProtoType *Proto  | 
 | 10605 |     = Constructor->getType()->getAs<FunctionProtoType>(); | 
 | 10606 |   assert(Proto && "Constructor without a prototype?"); | 
 | 10607 |   unsigned NumArgsInProto = Proto->getNumArgs(); | 
| Douglas Gregor | 39da0b8 | 2009-09-09 23:08:42 +0000 | [diff] [blame] | 10608 |    | 
 | 10609 |   // If too few arguments are available, we'll fill in the rest with defaults. | 
| Fariborz Jahanian | 2fe168f | 2009-11-24 21:37:28 +0000 | [diff] [blame] | 10610 |   if (NumArgs < NumArgsInProto) | 
| Douglas Gregor | 39da0b8 | 2009-09-09 23:08:42 +0000 | [diff] [blame] | 10611 |     ConvertedArgs.reserve(NumArgsInProto); | 
| Fariborz Jahanian | 2fe168f | 2009-11-24 21:37:28 +0000 | [diff] [blame] | 10612 |   else | 
| Douglas Gregor | 39da0b8 | 2009-09-09 23:08:42 +0000 | [diff] [blame] | 10613 |     ConvertedArgs.reserve(NumArgs); | 
| Fariborz Jahanian | 2fe168f | 2009-11-24 21:37:28 +0000 | [diff] [blame] | 10614 |  | 
 | 10615 |   VariadicCallType CallType =  | 
 | 10616 |     Proto->isVariadic() ? VariadicConstructor : VariadicDoesNotApply; | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 10617 |   SmallVector<Expr *, 8> AllArgs; | 
| Fariborz Jahanian | 2fe168f | 2009-11-24 21:37:28 +0000 | [diff] [blame] | 10618 |   bool Invalid = GatherArgumentsForCall(Loc, Constructor, | 
| Dmitri Gribenko | 9e00f12 | 2013-05-09 21:02:07 +0000 | [diff] [blame] | 10619 |                                         Proto, 0, | 
 | 10620 |                                         llvm::makeArrayRef(Args, NumArgs), | 
 | 10621 |                                         AllArgs, | 
| Richard Smith | a4dc51b | 2013-02-05 05:52:24 +0000 | [diff] [blame] | 10622 |                                         CallType, AllowExplicit, | 
 | 10623 |                                         IsListInitialization); | 
| Benjamin Kramer | 14c5982 | 2012-02-14 12:06:21 +0000 | [diff] [blame] | 10624 |   ConvertedArgs.append(AllArgs.begin(), AllArgs.end()); | 
| Eli Friedman | e61eb04 | 2012-02-18 04:48:30 +0000 | [diff] [blame] | 10625 |  | 
| Dmitri Gribenko | 9e00f12 | 2013-05-09 21:02:07 +0000 | [diff] [blame] | 10626 |   DiagnoseSentinelCalls(Constructor, Loc, AllArgs); | 
| Eli Friedman | e61eb04 | 2012-02-18 04:48:30 +0000 | [diff] [blame] | 10627 |  | 
| Dmitri Gribenko | 1c030e9 | 2013-01-13 20:46:02 +0000 | [diff] [blame] | 10628 |   CheckConstructorCall(Constructor, | 
 | 10629 |                        llvm::makeArrayRef<const Expr *>(AllArgs.data(), | 
 | 10630 |                                                         AllArgs.size()), | 
| Richard Smith | 831421f | 2012-06-25 20:30:08 +0000 | [diff] [blame] | 10631 |                        Proto, Loc); | 
| Eli Friedman | e61eb04 | 2012-02-18 04:48:30 +0000 | [diff] [blame] | 10632 |  | 
| Fariborz Jahanian | 2fe168f | 2009-11-24 21:37:28 +0000 | [diff] [blame] | 10633 |   return Invalid; | 
| Douglas Gregor | 18fe568 | 2008-11-03 20:45:27 +0000 | [diff] [blame] | 10634 | } | 
 | 10635 |  | 
| Anders Carlsson | 20d45d2 | 2009-12-12 00:32:00 +0000 | [diff] [blame] | 10636 | static inline bool | 
 | 10637 | CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef,  | 
 | 10638 |                                        const FunctionDecl *FnDecl) { | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 10639 |   const DeclContext *DC = FnDecl->getDeclContext()->getRedeclContext(); | 
| Anders Carlsson | 20d45d2 | 2009-12-12 00:32:00 +0000 | [diff] [blame] | 10640 |   if (isa<NamespaceDecl>(DC)) { | 
 | 10641 |     return SemaRef.Diag(FnDecl->getLocation(),  | 
 | 10642 |                         diag::err_operator_new_delete_declared_in_namespace) | 
 | 10643 |       << FnDecl->getDeclName(); | 
 | 10644 |   } | 
 | 10645 |    | 
 | 10646 |   if (isa<TranslationUnitDecl>(DC) &&  | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 10647 |       FnDecl->getStorageClass() == SC_Static) { | 
| Anders Carlsson | 20d45d2 | 2009-12-12 00:32:00 +0000 | [diff] [blame] | 10648 |     return SemaRef.Diag(FnDecl->getLocation(), | 
 | 10649 |                         diag::err_operator_new_delete_declared_static) | 
 | 10650 |       << FnDecl->getDeclName(); | 
 | 10651 |   } | 
 | 10652 |    | 
| Anders Carlsson | fcfdb2b | 2009-12-12 02:43:16 +0000 | [diff] [blame] | 10653 |   return false; | 
| Anders Carlsson | 20d45d2 | 2009-12-12 00:32:00 +0000 | [diff] [blame] | 10654 | } | 
 | 10655 |  | 
| Anders Carlsson | 156c78e | 2009-12-13 17:53:43 +0000 | [diff] [blame] | 10656 | static inline bool | 
 | 10657 | CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl, | 
 | 10658 |                             CanQualType ExpectedResultType, | 
 | 10659 |                             CanQualType ExpectedFirstParamType, | 
 | 10660 |                             unsigned DependentParamTypeDiag, | 
 | 10661 |                             unsigned InvalidParamTypeDiag) { | 
 | 10662 |   QualType ResultType =  | 
 | 10663 |     FnDecl->getType()->getAs<FunctionType>()->getResultType(); | 
 | 10664 |  | 
 | 10665 |   // Check that the result type is not dependent. | 
 | 10666 |   if (ResultType->isDependentType()) | 
 | 10667 |     return SemaRef.Diag(FnDecl->getLocation(), | 
 | 10668 |                         diag::err_operator_new_delete_dependent_result_type) | 
 | 10669 |     << FnDecl->getDeclName() << ExpectedResultType; | 
 | 10670 |  | 
 | 10671 |   // Check that the result type is what we expect. | 
 | 10672 |   if (SemaRef.Context.getCanonicalType(ResultType) != ExpectedResultType) | 
 | 10673 |     return SemaRef.Diag(FnDecl->getLocation(), | 
 | 10674 |                         diag::err_operator_new_delete_invalid_result_type)  | 
 | 10675 |     << FnDecl->getDeclName() << ExpectedResultType; | 
 | 10676 |    | 
 | 10677 |   // A function template must have at least 2 parameters. | 
 | 10678 |   if (FnDecl->getDescribedFunctionTemplate() && FnDecl->getNumParams() < 2) | 
 | 10679 |     return SemaRef.Diag(FnDecl->getLocation(), | 
 | 10680 |                       diag::err_operator_new_delete_template_too_few_parameters) | 
 | 10681 |         << FnDecl->getDeclName(); | 
 | 10682 |    | 
 | 10683 |   // The function decl must have at least 1 parameter. | 
 | 10684 |   if (FnDecl->getNumParams() == 0) | 
 | 10685 |     return SemaRef.Diag(FnDecl->getLocation(), | 
 | 10686 |                         diag::err_operator_new_delete_too_few_parameters) | 
 | 10687 |       << FnDecl->getDeclName(); | 
 | 10688 |   | 
| Sylvestre Ledru | bed28ac | 2012-07-23 08:59:39 +0000 | [diff] [blame] | 10689 |   // Check the first parameter type is not dependent. | 
| Anders Carlsson | 156c78e | 2009-12-13 17:53:43 +0000 | [diff] [blame] | 10690 |   QualType FirstParamType = FnDecl->getParamDecl(0)->getType(); | 
 | 10691 |   if (FirstParamType->isDependentType()) | 
 | 10692 |     return SemaRef.Diag(FnDecl->getLocation(), DependentParamTypeDiag) | 
 | 10693 |       << FnDecl->getDeclName() << ExpectedFirstParamType; | 
 | 10694 |  | 
 | 10695 |   // Check that the first parameter type is what we expect. | 
| Douglas Gregor | 6e790ab | 2009-12-22 23:42:49 +0000 | [diff] [blame] | 10696 |   if (SemaRef.Context.getCanonicalType(FirstParamType).getUnqualifiedType() !=  | 
| Anders Carlsson | 156c78e | 2009-12-13 17:53:43 +0000 | [diff] [blame] | 10697 |       ExpectedFirstParamType) | 
 | 10698 |     return SemaRef.Diag(FnDecl->getLocation(), InvalidParamTypeDiag) | 
 | 10699 |     << FnDecl->getDeclName() << ExpectedFirstParamType; | 
 | 10700 |    | 
 | 10701 |   return false; | 
 | 10702 | } | 
 | 10703 |  | 
| Anders Carlsson | 9d59ecb | 2009-12-11 23:23:22 +0000 | [diff] [blame] | 10704 | static bool | 
| Anders Carlsson | 156c78e | 2009-12-13 17:53:43 +0000 | [diff] [blame] | 10705 | CheckOperatorNewDeclaration(Sema &SemaRef, const FunctionDecl *FnDecl) { | 
| Anders Carlsson | 20d45d2 | 2009-12-12 00:32:00 +0000 | [diff] [blame] | 10706 |   // C++ [basic.stc.dynamic.allocation]p1: | 
 | 10707 |   //   A program is ill-formed if an allocation function is declared in a | 
 | 10708 |   //   namespace scope other than global scope or declared static in global  | 
 | 10709 |   //   scope. | 
 | 10710 |   if (CheckOperatorNewDeleteDeclarationScope(SemaRef, FnDecl)) | 
 | 10711 |     return true; | 
| Anders Carlsson | 156c78e | 2009-12-13 17:53:43 +0000 | [diff] [blame] | 10712 |  | 
 | 10713 |   CanQualType SizeTy =  | 
 | 10714 |     SemaRef.Context.getCanonicalType(SemaRef.Context.getSizeType()); | 
 | 10715 |  | 
 | 10716 |   // C++ [basic.stc.dynamic.allocation]p1: | 
 | 10717 |   //  The return type shall be void*. The first parameter shall have type  | 
 | 10718 |   //  std::size_t. | 
 | 10719 |   if (CheckOperatorNewDeleteTypes(SemaRef, FnDecl, SemaRef.Context.VoidPtrTy,  | 
 | 10720 |                                   SizeTy, | 
 | 10721 |                                   diag::err_operator_new_dependent_param_type, | 
 | 10722 |                                   diag::err_operator_new_param_type)) | 
 | 10723 |     return true; | 
 | 10724 |  | 
 | 10725 |   // C++ [basic.stc.dynamic.allocation]p1: | 
 | 10726 |   //  The first parameter shall not have an associated default argument. | 
 | 10727 |   if (FnDecl->getParamDecl(0)->hasDefaultArg()) | 
| Anders Carlsson | a3ccda5 | 2009-12-12 00:26:23 +0000 | [diff] [blame] | 10728 |     return SemaRef.Diag(FnDecl->getLocation(), | 
| Anders Carlsson | 156c78e | 2009-12-13 17:53:43 +0000 | [diff] [blame] | 10729 |                         diag::err_operator_new_default_arg) | 
 | 10730 |       << FnDecl->getDeclName() << FnDecl->getParamDecl(0)->getDefaultArgRange(); | 
 | 10731 |  | 
 | 10732 |   return false; | 
| Anders Carlsson | a3ccda5 | 2009-12-12 00:26:23 +0000 | [diff] [blame] | 10733 | } | 
 | 10734 |  | 
 | 10735 | static bool | 
| Richard Smith | 444d384 | 2012-10-20 08:26:51 +0000 | [diff] [blame] | 10736 | CheckOperatorDeleteDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) { | 
| Anders Carlsson | 9d59ecb | 2009-12-11 23:23:22 +0000 | [diff] [blame] | 10737 |   // C++ [basic.stc.dynamic.deallocation]p1: | 
 | 10738 |   //   A program is ill-formed if deallocation functions are declared in a | 
 | 10739 |   //   namespace scope other than global scope or declared static in global  | 
 | 10740 |   //   scope. | 
| Anders Carlsson | 20d45d2 | 2009-12-12 00:32:00 +0000 | [diff] [blame] | 10741 |   if (CheckOperatorNewDeleteDeclarationScope(SemaRef, FnDecl)) | 
 | 10742 |     return true; | 
| Anders Carlsson | 9d59ecb | 2009-12-11 23:23:22 +0000 | [diff] [blame] | 10743 |  | 
 | 10744 |   // C++ [basic.stc.dynamic.deallocation]p2: | 
 | 10745 |   //   Each deallocation function shall return void and its first parameter  | 
 | 10746 |   //   shall be void*. | 
| Anders Carlsson | 156c78e | 2009-12-13 17:53:43 +0000 | [diff] [blame] | 10747 |   if (CheckOperatorNewDeleteTypes(SemaRef, FnDecl, SemaRef.Context.VoidTy,  | 
 | 10748 |                                   SemaRef.Context.VoidPtrTy, | 
 | 10749 |                                  diag::err_operator_delete_dependent_param_type, | 
 | 10750 |                                  diag::err_operator_delete_param_type)) | 
 | 10751 |     return true; | 
| Anders Carlsson | 9d59ecb | 2009-12-11 23:23:22 +0000 | [diff] [blame] | 10752 |  | 
| Anders Carlsson | 9d59ecb | 2009-12-11 23:23:22 +0000 | [diff] [blame] | 10753 |   return false; | 
 | 10754 | } | 
 | 10755 |  | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10756 | /// CheckOverloadedOperatorDeclaration - Check whether the declaration | 
 | 10757 | /// of this overloaded operator is well-formed. If so, returns false; | 
 | 10758 | /// otherwise, emits appropriate diagnostics and returns true. | 
 | 10759 | bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) { | 
| Douglas Gregor | 43c7bad | 2008-11-17 16:14:12 +0000 | [diff] [blame] | 10760 |   assert(FnDecl && FnDecl->isOverloadedOperator() && | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10761 |          "Expected an overloaded operator declaration"); | 
 | 10762 |  | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10763 |   OverloadedOperatorKind Op = FnDecl->getOverloadedOperator(); | 
 | 10764 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10765 |   // C++ [over.oper]p5: | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10766 |   //   The allocation and deallocation functions, operator new, | 
 | 10767 |   //   operator new[], operator delete and operator delete[], are | 
 | 10768 |   //   described completely in 3.7.3. The attributes and restrictions | 
 | 10769 |   //   found in the rest of this subclause do not apply to them unless | 
 | 10770 |   //   explicitly stated in 3.7.3. | 
| Anders Carlsson | 1152c39 | 2009-12-11 23:31:21 +0000 | [diff] [blame] | 10771 |   if (Op == OO_Delete || Op == OO_Array_Delete) | 
| Anders Carlsson | 9d59ecb | 2009-12-11 23:23:22 +0000 | [diff] [blame] | 10772 |     return CheckOperatorDeleteDeclaration(*this, FnDecl); | 
| Fariborz Jahanian | b03bfa5 | 2009-11-10 23:47:18 +0000 | [diff] [blame] | 10773 |    | 
| Anders Carlsson | a3ccda5 | 2009-12-12 00:26:23 +0000 | [diff] [blame] | 10774 |   if (Op == OO_New || Op == OO_Array_New) | 
 | 10775 |     return CheckOperatorNewDeclaration(*this, FnDecl); | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10776 |  | 
 | 10777 |   // C++ [over.oper]p6: | 
 | 10778 |   //   An operator function shall either be a non-static member | 
 | 10779 |   //   function or be a non-member function and have at least one | 
 | 10780 |   //   parameter whose type is a class, a reference to a class, an | 
 | 10781 |   //   enumeration, or a reference to an enumeration. | 
| Douglas Gregor | 43c7bad | 2008-11-17 16:14:12 +0000 | [diff] [blame] | 10782 |   if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(FnDecl)) { | 
 | 10783 |     if (MethodDecl->isStatic()) | 
 | 10784 |       return Diag(FnDecl->getLocation(), | 
| Chris Lattner | d9d22dd | 2008-11-24 05:29:24 +0000 | [diff] [blame] | 10785 |                   diag::err_operator_overload_static) << FnDecl->getDeclName(); | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10786 |   } else { | 
 | 10787 |     bool ClassOrEnumParam = false; | 
| Douglas Gregor | 43c7bad | 2008-11-17 16:14:12 +0000 | [diff] [blame] | 10788 |     for (FunctionDecl::param_iterator Param = FnDecl->param_begin(), | 
 | 10789 |                                    ParamEnd = FnDecl->param_end(); | 
 | 10790 |          Param != ParamEnd; ++Param) { | 
 | 10791 |       QualType ParamType = (*Param)->getType().getNonReferenceType(); | 
| Eli Friedman | 5d39dee | 2009-06-27 05:59:59 +0000 | [diff] [blame] | 10792 |       if (ParamType->isDependentType() || ParamType->isRecordType() || | 
 | 10793 |           ParamType->isEnumeralType()) { | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10794 |         ClassOrEnumParam = true; | 
 | 10795 |         break; | 
 | 10796 |       } | 
 | 10797 |     } | 
 | 10798 |  | 
| Douglas Gregor | 43c7bad | 2008-11-17 16:14:12 +0000 | [diff] [blame] | 10799 |     if (!ClassOrEnumParam) | 
 | 10800 |       return Diag(FnDecl->getLocation(), | 
| Chris Lattner | f3a41af | 2008-11-20 06:38:18 +0000 | [diff] [blame] | 10801 |                   diag::err_operator_overload_needs_class_or_enum) | 
| Chris Lattner | d9d22dd | 2008-11-24 05:29:24 +0000 | [diff] [blame] | 10802 |         << FnDecl->getDeclName(); | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10803 |   } | 
 | 10804 |  | 
 | 10805 |   // C++ [over.oper]p8: | 
 | 10806 |   //   An operator function cannot have default arguments (8.3.6), | 
 | 10807 |   //   except where explicitly stated below. | 
 | 10808 |   // | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10809 |   // Only the function-call operator allows default arguments | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10810 |   // (C++ [over.call]p1). | 
 | 10811 |   if (Op != OO_Call) { | 
 | 10812 |     for (FunctionDecl::param_iterator Param = FnDecl->param_begin(); | 
 | 10813 |          Param != FnDecl->param_end(); ++Param) { | 
| Anders Carlsson | 156c78e | 2009-12-13 17:53:43 +0000 | [diff] [blame] | 10814 |       if ((*Param)->hasDefaultArg()) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10815 |         return Diag((*Param)->getLocation(), | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 10816 |                     diag::err_operator_overload_default_arg) | 
| Anders Carlsson | 156c78e | 2009-12-13 17:53:43 +0000 | [diff] [blame] | 10817 |           << FnDecl->getDeclName() << (*Param)->getDefaultArgRange(); | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10818 |     } | 
 | 10819 |   } | 
 | 10820 |  | 
| Douglas Gregor | 02bcd4c | 2008-11-10 13:38:07 +0000 | [diff] [blame] | 10821 |   static const bool OperatorUses[NUM_OVERLOADED_OPERATORS][3] = { | 
 | 10822 |     { false, false, false } | 
 | 10823 | #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ | 
 | 10824 |     , { Unary, Binary, MemberOnly } | 
 | 10825 | #include "clang/Basic/OperatorKinds.def" | 
 | 10826 |   }; | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10827 |  | 
| Douglas Gregor | 02bcd4c | 2008-11-10 13:38:07 +0000 | [diff] [blame] | 10828 |   bool CanBeUnaryOperator = OperatorUses[Op][0]; | 
 | 10829 |   bool CanBeBinaryOperator = OperatorUses[Op][1]; | 
 | 10830 |   bool MustBeMemberOperator = OperatorUses[Op][2]; | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10831 |  | 
 | 10832 |   // C++ [over.oper]p8: | 
 | 10833 |   //   [...] Operator functions cannot have more or fewer parameters | 
 | 10834 |   //   than the number required for the corresponding operator, as | 
 | 10835 |   //   described in the rest of this subclause. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10836 |   unsigned NumParams = FnDecl->getNumParams() | 
| Douglas Gregor | 43c7bad | 2008-11-17 16:14:12 +0000 | [diff] [blame] | 10837 |                      + (isa<CXXMethodDecl>(FnDecl)? 1 : 0); | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10838 |   if (Op != OO_Call && | 
 | 10839 |       ((NumParams == 1 && !CanBeUnaryOperator) || | 
 | 10840 |        (NumParams == 2 && !CanBeBinaryOperator) || | 
 | 10841 |        (NumParams < 1) || (NumParams > 2))) { | 
 | 10842 |     // We have the wrong number of parameters. | 
| Chris Lattner | 416e46f | 2008-11-21 07:57:12 +0000 | [diff] [blame] | 10843 |     unsigned ErrorKind; | 
| Douglas Gregor | 02bcd4c | 2008-11-10 13:38:07 +0000 | [diff] [blame] | 10844 |     if (CanBeUnaryOperator && CanBeBinaryOperator) { | 
| Chris Lattner | 416e46f | 2008-11-21 07:57:12 +0000 | [diff] [blame] | 10845 |       ErrorKind = 2;  // 2 -> unary or binary. | 
| Douglas Gregor | 02bcd4c | 2008-11-10 13:38:07 +0000 | [diff] [blame] | 10846 |     } else if (CanBeUnaryOperator) { | 
| Chris Lattner | 416e46f | 2008-11-21 07:57:12 +0000 | [diff] [blame] | 10847 |       ErrorKind = 0;  // 0 -> unary | 
| Douglas Gregor | 02bcd4c | 2008-11-10 13:38:07 +0000 | [diff] [blame] | 10848 |     } else { | 
| Chris Lattner | af7ae4e | 2008-11-21 07:50:02 +0000 | [diff] [blame] | 10849 |       assert(CanBeBinaryOperator && | 
 | 10850 |              "All non-call overloaded operators are unary or binary!"); | 
| Chris Lattner | 416e46f | 2008-11-21 07:57:12 +0000 | [diff] [blame] | 10851 |       ErrorKind = 1;  // 1 -> binary | 
| Douglas Gregor | 02bcd4c | 2008-11-10 13:38:07 +0000 | [diff] [blame] | 10852 |     } | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10853 |  | 
| Chris Lattner | 416e46f | 2008-11-21 07:57:12 +0000 | [diff] [blame] | 10854 |     return Diag(FnDecl->getLocation(), diag::err_operator_overload_must_be) | 
| Chris Lattner | d9d22dd | 2008-11-24 05:29:24 +0000 | [diff] [blame] | 10855 |       << FnDecl->getDeclName() << NumParams << ErrorKind; | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10856 |   } | 
| Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 10857 |  | 
| Douglas Gregor | 43c7bad | 2008-11-17 16:14:12 +0000 | [diff] [blame] | 10858 |   // Overloaded operators other than operator() cannot be variadic. | 
 | 10859 |   if (Op != OO_Call && | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 10860 |       FnDecl->getType()->getAs<FunctionProtoType>()->isVariadic()) { | 
| Chris Lattner | f3a41af | 2008-11-20 06:38:18 +0000 | [diff] [blame] | 10861 |     return Diag(FnDecl->getLocation(), diag::err_operator_overload_variadic) | 
| Chris Lattner | d9d22dd | 2008-11-24 05:29:24 +0000 | [diff] [blame] | 10862 |       << FnDecl->getDeclName(); | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10863 |   } | 
 | 10864 |  | 
 | 10865 |   // Some operators must be non-static member functions. | 
| Douglas Gregor | 43c7bad | 2008-11-17 16:14:12 +0000 | [diff] [blame] | 10866 |   if (MustBeMemberOperator && !isa<CXXMethodDecl>(FnDecl)) { | 
 | 10867 |     return Diag(FnDecl->getLocation(), | 
| Chris Lattner | f3a41af | 2008-11-20 06:38:18 +0000 | [diff] [blame] | 10868 |                 diag::err_operator_overload_must_be_member) | 
| Chris Lattner | d9d22dd | 2008-11-24 05:29:24 +0000 | [diff] [blame] | 10869 |       << FnDecl->getDeclName(); | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10870 |   } | 
 | 10871 |  | 
 | 10872 |   // C++ [over.inc]p1: | 
 | 10873 |   //   The user-defined function called operator++ implements the | 
 | 10874 |   //   prefix and postfix ++ operator. If this function is a member | 
 | 10875 |   //   function with no parameters, or a non-member function with one | 
 | 10876 |   //   parameter of class or enumeration type, it defines the prefix | 
 | 10877 |   //   increment operator ++ for objects of that type. If the function | 
 | 10878 |   //   is a member function with one parameter (which shall be of type | 
 | 10879 |   //   int) or a non-member function with two parameters (the second | 
 | 10880 |   //   of which shall be of type int), it defines the postfix | 
 | 10881 |   //   increment operator ++ for objects of that type. | 
 | 10882 |   if ((Op == OO_PlusPlus || Op == OO_MinusMinus) && NumParams == 2) { | 
 | 10883 |     ParmVarDecl *LastParam = FnDecl->getParamDecl(FnDecl->getNumParams() - 1); | 
 | 10884 |     bool ParamIsInt = false; | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 10885 |     if (const BuiltinType *BT = LastParam->getType()->getAs<BuiltinType>()) | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10886 |       ParamIsInt = BT->getKind() == BuiltinType::Int; | 
 | 10887 |  | 
| Chris Lattner | af7ae4e | 2008-11-21 07:50:02 +0000 | [diff] [blame] | 10888 |     if (!ParamIsInt) | 
 | 10889 |       return Diag(LastParam->getLocation(), | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10890 |                   diag::err_operator_overload_post_incdec_must_be_int) | 
| Chris Lattner | d162584 | 2008-11-24 06:25:27 +0000 | [diff] [blame] | 10891 |         << LastParam->getType() << (Op == OO_MinusMinus); | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10892 |   } | 
 | 10893 |  | 
| Douglas Gregor | 43c7bad | 2008-11-17 16:14:12 +0000 | [diff] [blame] | 10894 |   return false; | 
| Douglas Gregor | 1cd1b1e | 2008-11-06 22:13:31 +0000 | [diff] [blame] | 10895 | } | 
| Chris Lattner | 5a003a4 | 2008-12-17 07:09:26 +0000 | [diff] [blame] | 10896 |  | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10897 | /// CheckLiteralOperatorDeclaration - Check whether the declaration | 
 | 10898 | /// of this literal operator function is well-formed. If so, returns | 
 | 10899 | /// false; otherwise, emits appropriate diagnostics and returns true. | 
 | 10900 | bool Sema::CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl) { | 
| Richard Smith | e5658f0 | 2012-03-10 22:18:57 +0000 | [diff] [blame] | 10901 |   if (isa<CXXMethodDecl>(FnDecl)) { | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10902 |     Diag(FnDecl->getLocation(), diag::err_literal_operator_outside_namespace) | 
 | 10903 |       << FnDecl->getDeclName(); | 
 | 10904 |     return true; | 
 | 10905 |   } | 
 | 10906 |  | 
| Richard Smith | b4a7b1e | 2012-03-04 09:41:16 +0000 | [diff] [blame] | 10907 |   if (FnDecl->isExternC()) { | 
 | 10908 |     Diag(FnDecl->getLocation(), diag::err_literal_operator_extern_c); | 
 | 10909 |     return true; | 
 | 10910 |   } | 
 | 10911 |  | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10912 |   bool Valid = false; | 
 | 10913 |  | 
| Richard Smith | 36f5cfe | 2012-03-09 08:00:36 +0000 | [diff] [blame] | 10914 |   // This might be the definition of a literal operator template. | 
 | 10915 |   FunctionTemplateDecl *TpDecl = FnDecl->getDescribedFunctionTemplate(); | 
 | 10916 |   // This might be a specialization of a literal operator template. | 
 | 10917 |   if (!TpDecl) | 
 | 10918 |     TpDecl = FnDecl->getPrimaryTemplate(); | 
 | 10919 |  | 
| Richard Smith | b328e29 | 2013-10-07 19:57:58 +0000 | [diff] [blame] | 10920 |   // template <char...> type operator "" name() and | 
 | 10921 |   // template <class T, T...> type operator "" name() are the only valid | 
 | 10922 |   // template signatures, and the only valid signatures with no parameters. | 
| Richard Smith | 36f5cfe | 2012-03-09 08:00:36 +0000 | [diff] [blame] | 10923 |   if (TpDecl) { | 
| Richard Smith | b4a7b1e | 2012-03-04 09:41:16 +0000 | [diff] [blame] | 10924 |     if (FnDecl->param_size() == 0) { | 
| Richard Smith | b328e29 | 2013-10-07 19:57:58 +0000 | [diff] [blame] | 10925 |       // Must have one or two template parameters | 
| Sean Hunt | 216c278 | 2010-04-07 23:11:06 +0000 | [diff] [blame] | 10926 |       TemplateParameterList *Params = TpDecl->getTemplateParameters(); | 
 | 10927 |       if (Params->size() == 1) { | 
 | 10928 |         NonTypeTemplateParmDecl *PmDecl = | 
| Richard Smith | 5295b97 | 2012-08-03 21:14:57 +0000 | [diff] [blame] | 10929 |           dyn_cast<NonTypeTemplateParmDecl>(Params->getParam(0)); | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10930 |  | 
| Sean Hunt | 216c278 | 2010-04-07 23:11:06 +0000 | [diff] [blame] | 10931 |         // The template parameter must be a char parameter pack. | 
| Sean Hunt | 216c278 | 2010-04-07 23:11:06 +0000 | [diff] [blame] | 10932 |         if (PmDecl && PmDecl->isTemplateParameterPack() && | 
 | 10933 |             Context.hasSameType(PmDecl->getType(), Context.CharTy)) | 
 | 10934 |           Valid = true; | 
| Richard Smith | b328e29 | 2013-10-07 19:57:58 +0000 | [diff] [blame] | 10935 |       } else if (Params->size() == 2) { | 
 | 10936 |         TemplateTypeParmDecl *PmType = | 
 | 10937 |           dyn_cast<TemplateTypeParmDecl>(Params->getParam(0)); | 
 | 10938 |         NonTypeTemplateParmDecl *PmArgs = | 
 | 10939 |           dyn_cast<NonTypeTemplateParmDecl>(Params->getParam(1)); | 
 | 10940 |  | 
 | 10941 |         // The second template parameter must be a parameter pack with the | 
 | 10942 |         // first template parameter as its type. | 
 | 10943 |         if (PmType && PmArgs && | 
 | 10944 |             !PmType->isTemplateParameterPack() && | 
 | 10945 |             PmArgs->isTemplateParameterPack()) { | 
 | 10946 |           const TemplateTypeParmType *TArgs = | 
 | 10947 |             PmArgs->getType()->getAs<TemplateTypeParmType>(); | 
 | 10948 |           if (TArgs && TArgs->getDepth() == PmType->getDepth() && | 
 | 10949 |               TArgs->getIndex() == PmType->getIndex()) { | 
 | 10950 |             Valid = true; | 
 | 10951 |             if (ActiveTemplateInstantiations.empty()) | 
 | 10952 |               Diag(FnDecl->getLocation(), | 
 | 10953 |                    diag::ext_string_literal_operator_template); | 
 | 10954 |           } | 
 | 10955 |         } | 
| Sean Hunt | 216c278 | 2010-04-07 23:11:06 +0000 | [diff] [blame] | 10956 |       } | 
 | 10957 |     } | 
| Richard Smith | b4a7b1e | 2012-03-04 09:41:16 +0000 | [diff] [blame] | 10958 |   } else if (FnDecl->param_size()) { | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10959 |     // Check the first parameter | 
| Sean Hunt | 216c278 | 2010-04-07 23:11:06 +0000 | [diff] [blame] | 10960 |     FunctionDecl::param_iterator Param = FnDecl->param_begin(); | 
 | 10961 |  | 
| Richard Smith | b4a7b1e | 2012-03-04 09:41:16 +0000 | [diff] [blame] | 10962 |     QualType T = (*Param)->getType().getUnqualifiedType(); | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10963 |  | 
| Sean Hunt | 30019c0 | 2010-04-07 22:57:35 +0000 | [diff] [blame] | 10964 |     // unsigned long long int, long double, and any character type are allowed | 
 | 10965 |     // as the only parameters. | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10966 |     if (Context.hasSameType(T, Context.UnsignedLongLongTy) || | 
 | 10967 |         Context.hasSameType(T, Context.LongDoubleTy) || | 
 | 10968 |         Context.hasSameType(T, Context.CharTy) || | 
| Hans Wennborg | 15f92ba | 2013-05-10 10:08:40 +0000 | [diff] [blame] | 10969 |         Context.hasSameType(T, Context.WideCharTy) || | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10970 |         Context.hasSameType(T, Context.Char16Ty) || | 
 | 10971 |         Context.hasSameType(T, Context.Char32Ty)) { | 
 | 10972 |       if (++Param == FnDecl->param_end()) | 
 | 10973 |         Valid = true; | 
 | 10974 |       goto FinishedParams; | 
 | 10975 |     } | 
 | 10976 |  | 
| Sean Hunt | 30019c0 | 2010-04-07 22:57:35 +0000 | [diff] [blame] | 10977 |     // Otherwise it must be a pointer to const; let's strip those qualifiers. | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10978 |     const PointerType *PT = T->getAs<PointerType>(); | 
 | 10979 |     if (!PT) | 
 | 10980 |       goto FinishedParams; | 
 | 10981 |     T = PT->getPointeeType(); | 
| Richard Smith | b4a7b1e | 2012-03-04 09:41:16 +0000 | [diff] [blame] | 10982 |     if (!T.isConstQualified() || T.isVolatileQualified()) | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 10983 |       goto FinishedParams; | 
 | 10984 |     T = T.getUnqualifiedType(); | 
 | 10985 |  | 
 | 10986 |     // Move on to the second parameter; | 
 | 10987 |     ++Param; | 
 | 10988 |  | 
 | 10989 |     // If there is no second parameter, the first must be a const char * | 
 | 10990 |     if (Param == FnDecl->param_end()) { | 
 | 10991 |       if (Context.hasSameType(T, Context.CharTy)) | 
 | 10992 |         Valid = true; | 
 | 10993 |       goto FinishedParams; | 
 | 10994 |     } | 
 | 10995 |  | 
 | 10996 |     // const char *, const wchar_t*, const char16_t*, and const char32_t* | 
 | 10997 |     // are allowed as the first parameter to a two-parameter function | 
 | 10998 |     if (!(Context.hasSameType(T, Context.CharTy) || | 
| Hans Wennborg | 15f92ba | 2013-05-10 10:08:40 +0000 | [diff] [blame] | 10999 |           Context.hasSameType(T, Context.WideCharTy) || | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 11000 |           Context.hasSameType(T, Context.Char16Ty) || | 
 | 11001 |           Context.hasSameType(T, Context.Char32Ty))) | 
 | 11002 |       goto FinishedParams; | 
 | 11003 |  | 
 | 11004 |     // The second and final parameter must be an std::size_t | 
 | 11005 |     T = (*Param)->getType().getUnqualifiedType(); | 
 | 11006 |     if (Context.hasSameType(T, Context.getSizeType()) && | 
 | 11007 |         ++Param == FnDecl->param_end()) | 
 | 11008 |       Valid = true; | 
 | 11009 |   } | 
 | 11010 |  | 
 | 11011 |   // FIXME: This diagnostic is absolutely terrible. | 
 | 11012 | FinishedParams: | 
 | 11013 |   if (!Valid) { | 
 | 11014 |     Diag(FnDecl->getLocation(), diag::err_literal_operator_params) | 
 | 11015 |       << FnDecl->getDeclName(); | 
 | 11016 |     return true; | 
 | 11017 |   } | 
 | 11018 |  | 
| Richard Smith | a9e88b2 | 2012-03-09 08:16:22 +0000 | [diff] [blame] | 11019 |   // A parameter-declaration-clause containing a default argument is not | 
 | 11020 |   // equivalent to any of the permitted forms. | 
 | 11021 |   for (FunctionDecl::param_iterator Param = FnDecl->param_begin(), | 
 | 11022 |                                     ParamEnd = FnDecl->param_end(); | 
 | 11023 |        Param != ParamEnd; ++Param) { | 
 | 11024 |     if ((*Param)->hasDefaultArg()) { | 
 | 11025 |       Diag((*Param)->getDefaultArgRange().getBegin(), | 
 | 11026 |            diag::err_literal_operator_default_argument) | 
 | 11027 |         << (*Param)->getDefaultArgRange(); | 
 | 11028 |       break; | 
 | 11029 |     } | 
 | 11030 |   } | 
 | 11031 |  | 
| Richard Smith | 2fb4ae3 | 2012-03-08 02:39:21 +0000 | [diff] [blame] | 11032 |   StringRef LiteralName | 
| Douglas Gregor | 1155c42 | 2011-08-30 22:40:35 +0000 | [diff] [blame] | 11033 |     = FnDecl->getDeclName().getCXXLiteralIdentifier()->getName(); | 
 | 11034 |   if (LiteralName[0] != '_') { | 
| Richard Smith | 2fb4ae3 | 2012-03-08 02:39:21 +0000 | [diff] [blame] | 11035 |     // C++11 [usrlit.suffix]p1: | 
 | 11036 |     //   Literal suffix identifiers that do not start with an underscore | 
 | 11037 |     //   are reserved for future standardization. | 
| Richard Smith | 4ac537b | 2013-07-23 08:14:48 +0000 | [diff] [blame] | 11038 |     Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved) | 
 | 11039 |       << NumericLiteralParser::isValidUDSuffix(getLangOpts(), LiteralName); | 
| Douglas Gregor | 1155c42 | 2011-08-30 22:40:35 +0000 | [diff] [blame] | 11040 |   } | 
| Richard Smith | 2fb4ae3 | 2012-03-08 02:39:21 +0000 | [diff] [blame] | 11041 |  | 
| Sean Hunt | a6c058d | 2010-01-13 09:01:02 +0000 | [diff] [blame] | 11042 |   return false; | 
 | 11043 | } | 
 | 11044 |  | 
| Douglas Gregor | 074149e | 2009-01-05 19:45:36 +0000 | [diff] [blame] | 11045 | /// ActOnStartLinkageSpecification - Parsed the beginning of a C++ | 
 | 11046 | /// linkage specification, including the language and (if present) | 
 | 11047 | /// the '{'. ExternLoc is the location of the 'extern', LangLoc is | 
 | 11048 | /// the location of the language string literal, which is provided | 
 | 11049 | /// by Lang/StrSize. LBraceLoc, if valid, provides the location of | 
 | 11050 | /// the '{' brace. Otherwise, this linkage specification does not | 
 | 11051 | /// have any braces. | 
| Chris Lattner | 7d64271 | 2010-11-09 20:15:55 +0000 | [diff] [blame] | 11052 | Decl *Sema::ActOnStartLinkageSpecification(Scope *S, SourceLocation ExternLoc, | 
 | 11053 |                                            SourceLocation LangLoc, | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 11054 |                                            StringRef Lang, | 
| Chris Lattner | 7d64271 | 2010-11-09 20:15:55 +0000 | [diff] [blame] | 11055 |                                            SourceLocation LBraceLoc) { | 
| Chris Lattner | cc98eac | 2008-12-17 07:13:27 +0000 | [diff] [blame] | 11056 |   LinkageSpecDecl::LanguageIDs Language; | 
| Benjamin Kramer | d566381 | 2010-05-03 13:08:54 +0000 | [diff] [blame] | 11057 |   if (Lang == "\"C\"") | 
| Chris Lattner | cc98eac | 2008-12-17 07:13:27 +0000 | [diff] [blame] | 11058 |     Language = LinkageSpecDecl::lang_c; | 
| Benjamin Kramer | d566381 | 2010-05-03 13:08:54 +0000 | [diff] [blame] | 11059 |   else if (Lang == "\"C++\"") | 
| Chris Lattner | cc98eac | 2008-12-17 07:13:27 +0000 | [diff] [blame] | 11060 |     Language = LinkageSpecDecl::lang_cxx; | 
 | 11061 |   else { | 
| Douglas Gregor | 074149e | 2009-01-05 19:45:36 +0000 | [diff] [blame] | 11062 |     Diag(LangLoc, diag::err_bad_language); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11063 |     return 0; | 
| Chris Lattner | cc98eac | 2008-12-17 07:13:27 +0000 | [diff] [blame] | 11064 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11065 |  | 
| Chris Lattner | cc98eac | 2008-12-17 07:13:27 +0000 | [diff] [blame] | 11066 |   // FIXME: Add all the various semantics of linkage specifications | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11067 |  | 
| Douglas Gregor | 074149e | 2009-01-05 19:45:36 +0000 | [diff] [blame] | 11068 |   LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext, | 
| Rafael Espindola | e5e575d | 2013-04-26 01:30:23 +0000 | [diff] [blame] | 11069 |                                                ExternLoc, LangLoc, Language, | 
 | 11070 |                                                LBraceLoc.isValid()); | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 11071 |   CurContext->addDecl(D); | 
| Douglas Gregor | 074149e | 2009-01-05 19:45:36 +0000 | [diff] [blame] | 11072 |   PushDeclContext(S, D); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11073 |   return D; | 
| Chris Lattner | cc98eac | 2008-12-17 07:13:27 +0000 | [diff] [blame] | 11074 | } | 
 | 11075 |  | 
| Abramo Bagnara | 35f9a19 | 2010-07-30 16:47:02 +0000 | [diff] [blame] | 11076 | /// ActOnFinishLinkageSpecification - Complete the definition of | 
| Douglas Gregor | 074149e | 2009-01-05 19:45:36 +0000 | [diff] [blame] | 11077 | /// the C++ linkage specification LinkageSpec. If RBraceLoc is | 
 | 11078 | /// valid, it's the position of the closing '}' brace in a linkage | 
 | 11079 | /// specification that uses braces. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11080 | Decl *Sema::ActOnFinishLinkageSpecification(Scope *S, | 
| Abramo Bagnara | 5f6bcbe | 2011-03-03 14:52:38 +0000 | [diff] [blame] | 11081 |                                             Decl *LinkageSpec, | 
 | 11082 |                                             SourceLocation RBraceLoc) { | 
 | 11083 |   if (LinkageSpec) { | 
 | 11084 |     if (RBraceLoc.isValid()) { | 
 | 11085 |       LinkageSpecDecl* LSDecl = cast<LinkageSpecDecl>(LinkageSpec); | 
 | 11086 |       LSDecl->setRBraceLoc(RBraceLoc); | 
 | 11087 |     } | 
| Douglas Gregor | 074149e | 2009-01-05 19:45:36 +0000 | [diff] [blame] | 11088 |     PopDeclContext(); | 
| Abramo Bagnara | 5f6bcbe | 2011-03-03 14:52:38 +0000 | [diff] [blame] | 11089 |   } | 
| Douglas Gregor | 074149e | 2009-01-05 19:45:36 +0000 | [diff] [blame] | 11090 |   return LinkageSpec; | 
| Chris Lattner | 5a003a4 | 2008-12-17 07:09:26 +0000 | [diff] [blame] | 11091 | } | 
 | 11092 |  | 
| Michael Han | 684aa73 | 2013-02-22 17:15:32 +0000 | [diff] [blame] | 11093 | Decl *Sema::ActOnEmptyDeclaration(Scope *S, | 
 | 11094 |                                   AttributeList *AttrList, | 
 | 11095 |                                   SourceLocation SemiLoc) { | 
 | 11096 |   Decl *ED = EmptyDecl::Create(Context, CurContext, SemiLoc); | 
 | 11097 |   // Attribute declarations appertain to empty declaration so we handle | 
 | 11098 |   // them here. | 
 | 11099 |   if (AttrList) | 
 | 11100 |     ProcessDeclAttributeList(S, ED, AttrList); | 
| Richard Smith | 6b3d3e5 | 2013-02-20 19:22:51 +0000 | [diff] [blame] | 11101 |  | 
| Michael Han | 684aa73 | 2013-02-22 17:15:32 +0000 | [diff] [blame] | 11102 |   CurContext->addDecl(ED); | 
 | 11103 |   return ED; | 
| Richard Smith | 6b3d3e5 | 2013-02-20 19:22:51 +0000 | [diff] [blame] | 11104 | } | 
 | 11105 |  | 
| Douglas Gregor | d308e62 | 2009-05-18 20:51:54 +0000 | [diff] [blame] | 11106 | /// \brief Perform semantic analysis for the variable declaration that | 
 | 11107 | /// occurs within a C++ catch clause, returning the newly-created | 
 | 11108 | /// variable. | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 11109 | VarDecl *Sema::BuildExceptionDeclaration(Scope *S, | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 11110 |                                          TypeSourceInfo *TInfo, | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 11111 |                                          SourceLocation StartLoc, | 
 | 11112 |                                          SourceLocation Loc, | 
 | 11113 |                                          IdentifierInfo *Name) { | 
| Douglas Gregor | d308e62 | 2009-05-18 20:51:54 +0000 | [diff] [blame] | 11114 |   bool Invalid = false; | 
| Douglas Gregor | 83cb942 | 2010-09-09 17:09:21 +0000 | [diff] [blame] | 11115 |   QualType ExDeclType = TInfo->getType(); | 
 | 11116 |    | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11117 |   // Arrays and functions decay. | 
 | 11118 |   if (ExDeclType->isArrayType()) | 
 | 11119 |     ExDeclType = Context.getArrayDecayedType(ExDeclType); | 
 | 11120 |   else if (ExDeclType->isFunctionType()) | 
 | 11121 |     ExDeclType = Context.getPointerType(ExDeclType); | 
 | 11122 |  | 
 | 11123 |   // C++ 15.3p1: The exception-declaration shall not denote an incomplete type. | 
 | 11124 |   // The exception-declaration shall not denote a pointer or reference to an | 
 | 11125 |   // incomplete type, other than [cv] void*. | 
| Sebastian Redl | f2e21e5 | 2009-03-22 23:49:27 +0000 | [diff] [blame] | 11126 |   // N2844 forbids rvalue references. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11127 |   if (!ExDeclType->isDependentType() && ExDeclType->isRValueReferenceType()) { | 
| Douglas Gregor | 83cb942 | 2010-09-09 17:09:21 +0000 | [diff] [blame] | 11128 |     Diag(Loc, diag::err_catch_rvalue_ref); | 
| Sebastian Redl | f2e21e5 | 2009-03-22 23:49:27 +0000 | [diff] [blame] | 11129 |     Invalid = true; | 
 | 11130 |   } | 
| Douglas Gregor | d308e62 | 2009-05-18 20:51:54 +0000 | [diff] [blame] | 11131 |  | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11132 |   QualType BaseType = ExDeclType; | 
 | 11133 |   int Mode = 0; // 0 for direct type, 1 for pointer, 2 for reference | 
| Douglas Gregor | 4ec339f | 2009-01-19 19:26:10 +0000 | [diff] [blame] | 11134 |   unsigned DK = diag::err_catch_incomplete; | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 11135 |   if (const PointerType *Ptr = BaseType->getAs<PointerType>()) { | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11136 |     BaseType = Ptr->getPointeeType(); | 
 | 11137 |     Mode = 1; | 
| Douglas Gregor | ecd7b04 | 2012-01-24 19:01:26 +0000 | [diff] [blame] | 11138 |     DK = diag::err_catch_incomplete_ptr; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11139 |   } else if (const ReferenceType *Ref = BaseType->getAs<ReferenceType>()) { | 
| Sebastian Redl | f2e21e5 | 2009-03-22 23:49:27 +0000 | [diff] [blame] | 11140 |     // For the purpose of error recovery, we treat rvalue refs like lvalue refs. | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11141 |     BaseType = Ref->getPointeeType(); | 
 | 11142 |     Mode = 2; | 
| Douglas Gregor | ecd7b04 | 2012-01-24 19:01:26 +0000 | [diff] [blame] | 11143 |     DK = diag::err_catch_incomplete_ref; | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11144 |   } | 
| Sebastian Redl | f2e21e5 | 2009-03-22 23:49:27 +0000 | [diff] [blame] | 11145 |   if (!Invalid && (Mode == 0 || !BaseType->isVoidType()) && | 
| Douglas Gregor | ecd7b04 | 2012-01-24 19:01:26 +0000 | [diff] [blame] | 11146 |       !BaseType->isDependentType() && RequireCompleteType(Loc, BaseType, DK)) | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11147 |     Invalid = true; | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11148 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11149 |   if (!Invalid && !ExDeclType->isDependentType() && | 
| Douglas Gregor | d308e62 | 2009-05-18 20:51:54 +0000 | [diff] [blame] | 11150 |       RequireNonAbstractType(Loc, ExDeclType, | 
 | 11151 |                              diag::err_abstract_type_in_decl, | 
 | 11152 |                              AbstractVariableType)) | 
| Sebastian Redl | fef9f59 | 2009-04-27 21:03:30 +0000 | [diff] [blame] | 11153 |     Invalid = true; | 
 | 11154 |  | 
| John McCall | 5a18039 | 2010-07-24 00:37:23 +0000 | [diff] [blame] | 11155 |   // Only the non-fragile NeXT runtime currently supports C++ catches | 
 | 11156 |   // of ObjC types, and no runtime supports catching ObjC types by value. | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 11157 |   if (!Invalid && getLangOpts().ObjC1) { | 
| John McCall | 5a18039 | 2010-07-24 00:37:23 +0000 | [diff] [blame] | 11158 |     QualType T = ExDeclType; | 
 | 11159 |     if (const ReferenceType *RT = T->getAs<ReferenceType>()) | 
 | 11160 |       T = RT->getPointeeType(); | 
 | 11161 |  | 
 | 11162 |     if (T->isObjCObjectType()) { | 
 | 11163 |       Diag(Loc, diag::err_objc_object_catch); | 
 | 11164 |       Invalid = true; | 
 | 11165 |     } else if (T->isObjCObjectPointerType()) { | 
| John McCall | 260611a | 2012-06-20 06:18:46 +0000 | [diff] [blame] | 11166 |       // FIXME: should this be a test for macosx-fragile specifically? | 
 | 11167 |       if (getLangOpts().ObjCRuntime.isFragile()) | 
| Fariborz Jahanian | cf5abc7 | 2011-06-23 19:00:08 +0000 | [diff] [blame] | 11168 |         Diag(Loc, diag::warn_objc_pointer_cxx_catch_fragile); | 
| John McCall | 5a18039 | 2010-07-24 00:37:23 +0000 | [diff] [blame] | 11169 |     } | 
 | 11170 |   } | 
 | 11171 |  | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 11172 |   VarDecl *ExDecl = VarDecl::Create(Context, CurContext, StartLoc, Loc, Name, | 
| Rafael Espindola | d2615cc | 2013-04-03 19:27:57 +0000 | [diff] [blame] | 11173 |                                     ExDeclType, TInfo, SC_None); | 
| Douglas Gregor | 324b54d | 2010-05-03 18:51:14 +0000 | [diff] [blame] | 11174 |   ExDecl->setExceptionVariable(true); | 
 | 11175 |    | 
| Douglas Gregor | 9aab9c4 | 2011-12-10 01:22:52 +0000 | [diff] [blame] | 11176 |   // In ARC, infer 'retaining' for variables of retainable type. | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 11177 |   if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(ExDecl)) | 
| Douglas Gregor | 9aab9c4 | 2011-12-10 01:22:52 +0000 | [diff] [blame] | 11178 |     Invalid = true; | 
 | 11179 |  | 
| Douglas Gregor | c41b878 | 2011-07-06 18:14:43 +0000 | [diff] [blame] | 11180 |   if (!Invalid && !ExDeclType->isDependentType()) { | 
| John McCall | e996ffd | 2011-02-16 08:02:54 +0000 | [diff] [blame] | 11181 |     if (const RecordType *recordType = ExDeclType->getAs<RecordType>()) { | 
| John McCall | b760f11 | 2013-03-22 02:10:40 +0000 | [diff] [blame] | 11182 |       // Insulate this from anything else we might currently be parsing. | 
 | 11183 |       EnterExpressionEvaluationContext scope(*this, PotentiallyEvaluated); | 
 | 11184 |  | 
| Douglas Gregor | 6d18289 | 2010-03-05 23:38:39 +0000 | [diff] [blame] | 11185 |       // C++ [except.handle]p16: | 
| Nick Lewycky | ee0bc3b | 2013-09-22 10:06:57 +0000 | [diff] [blame] | 11186 |       //   The object declared in an exception-declaration or, if the | 
 | 11187 |       //   exception-declaration does not specify a name, a temporary (12.2) is | 
| Douglas Gregor | 6d18289 | 2010-03-05 23:38:39 +0000 | [diff] [blame] | 11188 |       //   copy-initialized (8.5) from the exception object. [...] | 
 | 11189 |       //   The object is destroyed when the handler exits, after the destruction | 
 | 11190 |       //   of any automatic objects initialized within the handler. | 
 | 11191 |       // | 
| Nick Lewycky | ee0bc3b | 2013-09-22 10:06:57 +0000 | [diff] [blame] | 11192 |       // We just pretend to initialize the object with itself, then make sure | 
| Douglas Gregor | 6d18289 | 2010-03-05 23:38:39 +0000 | [diff] [blame] | 11193 |       // it can be destroyed later. | 
| John McCall | e996ffd | 2011-02-16 08:02:54 +0000 | [diff] [blame] | 11194 |       QualType initType = ExDeclType; | 
 | 11195 |  | 
 | 11196 |       InitializedEntity entity = | 
 | 11197 |         InitializedEntity::InitializeVariable(ExDecl); | 
 | 11198 |       InitializationKind initKind = | 
 | 11199 |         InitializationKind::CreateCopy(Loc, SourceLocation()); | 
 | 11200 |  | 
 | 11201 |       Expr *opaqueValue = | 
 | 11202 |         new (Context) OpaqueValueExpr(Loc, initType, VK_LValue, OK_Ordinary); | 
| Dmitri Gribenko | 1f78a50 | 2013-05-03 15:05:50 +0000 | [diff] [blame] | 11203 |       InitializationSequence sequence(*this, entity, initKind, opaqueValue); | 
 | 11204 |       ExprResult result = sequence.Perform(*this, entity, initKind, opaqueValue); | 
| John McCall | e996ffd | 2011-02-16 08:02:54 +0000 | [diff] [blame] | 11205 |       if (result.isInvalid()) | 
| Douglas Gregor | 6d18289 | 2010-03-05 23:38:39 +0000 | [diff] [blame] | 11206 |         Invalid = true; | 
| John McCall | e996ffd | 2011-02-16 08:02:54 +0000 | [diff] [blame] | 11207 |       else { | 
 | 11208 |         // If the constructor used was non-trivial, set this as the | 
 | 11209 |         // "initializer". | 
| Nick Lewycky | ee0bc3b | 2013-09-22 10:06:57 +0000 | [diff] [blame] | 11210 |         CXXConstructExpr *construct = result.takeAs<CXXConstructExpr>(); | 
| John McCall | e996ffd | 2011-02-16 08:02:54 +0000 | [diff] [blame] | 11211 |         if (!construct->getConstructor()->isTrivial()) { | 
 | 11212 |           Expr *init = MaybeCreateExprWithCleanups(construct); | 
 | 11213 |           ExDecl->setInit(init); | 
 | 11214 |         } | 
 | 11215 |          | 
 | 11216 |         // And make sure it's destructable. | 
 | 11217 |         FinalizeVarWithDestructor(ExDecl, recordType); | 
 | 11218 |       } | 
| Douglas Gregor | 6d18289 | 2010-03-05 23:38:39 +0000 | [diff] [blame] | 11219 |     } | 
 | 11220 |   } | 
 | 11221 |    | 
| Douglas Gregor | d308e62 | 2009-05-18 20:51:54 +0000 | [diff] [blame] | 11222 |   if (Invalid) | 
 | 11223 |     ExDecl->setInvalidDecl(); | 
 | 11224 |  | 
 | 11225 |   return ExDecl; | 
 | 11226 | } | 
 | 11227 |  | 
 | 11228 | /// ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch | 
 | 11229 | /// handler. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11230 | Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) { | 
| John McCall | bf1a028 | 2010-06-04 23:28:52 +0000 | [diff] [blame] | 11231 |   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); | 
| Douglas Gregor | a669c53 | 2010-12-16 17:48:04 +0000 | [diff] [blame] | 11232 |   bool Invalid = D.isInvalidType(); | 
 | 11233 |  | 
 | 11234 |   // Check for unexpanded parameter packs. | 
| Jordan Rose | 41f3f3a | 2013-03-05 01:27:54 +0000 | [diff] [blame] | 11235 |   if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo, | 
 | 11236 |                                       UPPC_ExceptionType)) { | 
| Douglas Gregor | a669c53 | 2010-12-16 17:48:04 +0000 | [diff] [blame] | 11237 |     TInfo = Context.getTrivialTypeSourceInfo(Context.IntTy,  | 
 | 11238 |                                              D.getIdentifierLoc()); | 
 | 11239 |     Invalid = true; | 
 | 11240 |   } | 
 | 11241 |  | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11242 |   IdentifierInfo *II = D.getIdentifier(); | 
| Douglas Gregor | c83c687 | 2010-04-15 22:33:43 +0000 | [diff] [blame] | 11243 |   if (NamedDecl *PrevDecl = LookupSingleName(S, II, D.getIdentifierLoc(), | 
| Douglas Gregor | c0b3964 | 2010-04-15 23:40:53 +0000 | [diff] [blame] | 11244 |                                              LookupOrdinaryName, | 
 | 11245 |                                              ForRedeclaration)) { | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11246 |     // The scope should be freshly made just for us. There is just no way | 
 | 11247 |     // it contains any previous declaration. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11248 |     assert(!S->isDeclScope(PrevDecl)); | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11249 |     if (PrevDecl->isTemplateParameter()) { | 
 | 11250 |       // Maybe we will complain about the shadowed template parameter. | 
 | 11251 |       DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); | 
| Douglas Gregor | cb8f951 | 2011-10-20 17:58:49 +0000 | [diff] [blame] | 11252 |       PrevDecl = 0; | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11253 |     } | 
 | 11254 |   } | 
 | 11255 |  | 
| Chris Lattner | eaaebc7 | 2009-04-25 08:06:05 +0000 | [diff] [blame] | 11256 |   if (D.getCXXScopeSpec().isSet() && !Invalid) { | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11257 |     Diag(D.getIdentifierLoc(), diag::err_qualified_catch_declarator) | 
 | 11258 |       << D.getCXXScopeSpec().getRange(); | 
| Chris Lattner | eaaebc7 | 2009-04-25 08:06:05 +0000 | [diff] [blame] | 11259 |     Invalid = true; | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11260 |   } | 
 | 11261 |  | 
| Douglas Gregor | 83cb942 | 2010-09-09 17:09:21 +0000 | [diff] [blame] | 11262 |   VarDecl *ExDecl = BuildExceptionDeclaration(S, TInfo, | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 11263 |                                               D.getLocStart(), | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 11264 |                                               D.getIdentifierLoc(), | 
 | 11265 |                                               D.getIdentifier()); | 
| Chris Lattner | eaaebc7 | 2009-04-25 08:06:05 +0000 | [diff] [blame] | 11266 |   if (Invalid) | 
 | 11267 |     ExDecl->setInvalidDecl(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11268 |  | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11269 |   // Add the exception declaration into this scope. | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11270 |   if (II) | 
| Douglas Gregor | d308e62 | 2009-05-18 20:51:54 +0000 | [diff] [blame] | 11271 |     PushOnScopeChains(ExDecl, S); | 
 | 11272 |   else | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 11273 |     CurContext->addDecl(ExDecl); | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11274 |  | 
| Douglas Gregor | 9cdda0c | 2009-06-17 21:51:59 +0000 | [diff] [blame] | 11275 |   ProcessDeclAttributes(S, ExDecl, D); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11276 |   return ExDecl; | 
| Sebastian Redl | 4b07b29 | 2008-12-22 19:15:10 +0000 | [diff] [blame] | 11277 | } | 
| Anders Carlsson | fb31176 | 2009-03-14 00:25:26 +0000 | [diff] [blame] | 11278 |  | 
| Abramo Bagnara | a2026c9 | 2011-03-08 16:41:52 +0000 | [diff] [blame] | 11279 | Decl *Sema::ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 11280 |                                          Expr *AssertExpr, | 
| Richard Smith | e3f470a | 2012-07-11 22:37:56 +0000 | [diff] [blame] | 11281 |                                          Expr *AssertMessageExpr, | 
| Abramo Bagnara | a2026c9 | 2011-03-08 16:41:52 +0000 | [diff] [blame] | 11282 |                                          SourceLocation RParenLoc) { | 
| Richard Smith | e3f470a | 2012-07-11 22:37:56 +0000 | [diff] [blame] | 11283 |   StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr); | 
| Anders Carlsson | fb31176 | 2009-03-14 00:25:26 +0000 | [diff] [blame] | 11284 |  | 
| Richard Smith | e3f470a | 2012-07-11 22:37:56 +0000 | [diff] [blame] | 11285 |   if (DiagnoseUnexpandedParameterPack(AssertExpr, UPPC_StaticAssertExpression)) | 
 | 11286 |     return 0; | 
 | 11287 |  | 
 | 11288 |   return BuildStaticAssertDeclaration(StaticAssertLoc, AssertExpr, | 
 | 11289 |                                       AssertMessage, RParenLoc, false); | 
 | 11290 | } | 
 | 11291 |  | 
 | 11292 | Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, | 
 | 11293 |                                          Expr *AssertExpr, | 
 | 11294 |                                          StringLiteral *AssertMessage, | 
 | 11295 |                                          SourceLocation RParenLoc, | 
 | 11296 |                                          bool Failed) { | 
 | 11297 |   if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent() && | 
 | 11298 |       !Failed) { | 
| Richard Smith | 282e7e6 | 2012-02-04 09:53:13 +0000 | [diff] [blame] | 11299 |     // In a static_assert-declaration, the constant-expression shall be a | 
 | 11300 |     // constant expression that can be contextually converted to bool. | 
 | 11301 |     ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr); | 
 | 11302 |     if (Converted.isInvalid()) | 
| Richard Smith | e3f470a | 2012-07-11 22:37:56 +0000 | [diff] [blame] | 11303 |       Failed = true; | 
| Richard Smith | 282e7e6 | 2012-02-04 09:53:13 +0000 | [diff] [blame] | 11304 |  | 
| Richard Smith | daaefc5 | 2011-12-14 23:32:26 +0000 | [diff] [blame] | 11305 |     llvm::APSInt Cond; | 
| Richard Smith | e3f470a | 2012-07-11 22:37:56 +0000 | [diff] [blame] | 11306 |     if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond, | 
| Douglas Gregor | ab41fe9 | 2012-05-04 22:38:52 +0000 | [diff] [blame] | 11307 |           diag::err_static_assert_expression_is_not_constant, | 
| Richard Smith | 282e7e6 | 2012-02-04 09:53:13 +0000 | [diff] [blame] | 11308 |           /*AllowFold=*/false).isInvalid()) | 
| Richard Smith | e3f470a | 2012-07-11 22:37:56 +0000 | [diff] [blame] | 11309 |       Failed = true; | 
| Anders Carlsson | fb31176 | 2009-03-14 00:25:26 +0000 | [diff] [blame] | 11310 |  | 
| Richard Smith | e3f470a | 2012-07-11 22:37:56 +0000 | [diff] [blame] | 11311 |     if (!Failed && !Cond) { | 
| Dmitri Gribenko | cfa88f8 | 2013-01-12 19:30:44 +0000 | [diff] [blame] | 11312 |       SmallString<256> MsgBuffer; | 
| Richard Smith | 0cc323c | 2012-03-05 23:20:05 +0000 | [diff] [blame] | 11313 |       llvm::raw_svector_ostream Msg(MsgBuffer); | 
| Richard Smith | d1420c6 | 2012-08-16 03:56:14 +0000 | [diff] [blame] | 11314 |       AssertMessage->printPretty(Msg, 0, getPrintingPolicy()); | 
| Abramo Bagnara | a2026c9 | 2011-03-08 16:41:52 +0000 | [diff] [blame] | 11315 |       Diag(StaticAssertLoc, diag::err_static_assert_failed) | 
| Richard Smith | 0cc323c | 2012-03-05 23:20:05 +0000 | [diff] [blame] | 11316 |         << Msg.str() << AssertExpr->getSourceRange(); | 
| Richard Smith | e3f470a | 2012-07-11 22:37:56 +0000 | [diff] [blame] | 11317 |       Failed = true; | 
| Richard Smith | 0cc323c | 2012-03-05 23:20:05 +0000 | [diff] [blame] | 11318 |     } | 
| Anders Carlsson | c308241 | 2009-03-14 00:33:21 +0000 | [diff] [blame] | 11319 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11320 |  | 
| Abramo Bagnara | a2026c9 | 2011-03-08 16:41:52 +0000 | [diff] [blame] | 11321 |   Decl *Decl = StaticAssertDecl::Create(Context, CurContext, StaticAssertLoc, | 
| Richard Smith | e3f470a | 2012-07-11 22:37:56 +0000 | [diff] [blame] | 11322 |                                         AssertExpr, AssertMessage, RParenLoc, | 
 | 11323 |                                         Failed); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11324 |  | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 11325 |   CurContext->addDecl(Decl); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11326 |   return Decl; | 
| Anders Carlsson | fb31176 | 2009-03-14 00:25:26 +0000 | [diff] [blame] | 11327 | } | 
| Sebastian Redl | 50de12f | 2009-03-24 22:27:57 +0000 | [diff] [blame] | 11328 |  | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11329 | /// \brief Perform semantic analysis of the given friend type declaration. | 
 | 11330 | /// | 
 | 11331 | /// \returns A friend declaration that. | 
| Richard Smith | d6f80da | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 11332 | FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation LocStart, | 
| Abramo Bagnara | 0216df8 | 2011-10-29 20:52:52 +0000 | [diff] [blame] | 11333 |                                       SourceLocation FriendLoc, | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11334 |                                       TypeSourceInfo *TSInfo) { | 
 | 11335 |   assert(TSInfo && "NULL TypeSourceInfo for friend type declaration"); | 
 | 11336 |    | 
 | 11337 |   QualType T = TSInfo->getType(); | 
| Abramo Bagnara | bd054db | 2010-05-20 10:00:11 +0000 | [diff] [blame] | 11338 |   SourceRange TypeRange = TSInfo->getTypeLoc().getLocalSourceRange(); | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11339 |    | 
| Richard Smith | 6b13022 | 2011-10-18 21:39:00 +0000 | [diff] [blame] | 11340 |   // C++03 [class.friend]p2: | 
 | 11341 |   //   An elaborated-type-specifier shall be used in a friend declaration | 
 | 11342 |   //   for a class.* | 
 | 11343 |   // | 
 | 11344 |   //   * The class-key of the elaborated-type-specifier is required. | 
 | 11345 |   if (!ActiveTemplateInstantiations.empty()) { | 
 | 11346 |     // Do not complain about the form of friend template types during | 
 | 11347 |     // template instantiation; we will already have complained when the | 
 | 11348 |     // template was declared. | 
| Nick Lewycky | ce6a10e | 2013-02-06 05:59:33 +0000 | [diff] [blame] | 11349 |   } else { | 
 | 11350 |     if (!T->isElaboratedTypeSpecifier()) { | 
 | 11351 |       // If we evaluated the type to a record type, suggest putting | 
 | 11352 |       // a tag in front. | 
 | 11353 |       if (const RecordType *RT = T->getAs<RecordType>()) { | 
 | 11354 |         RecordDecl *RD = RT->getDecl(); | 
| Richard Smith | 6b13022 | 2011-10-18 21:39:00 +0000 | [diff] [blame] | 11355 |        | 
| Nick Lewycky | ce6a10e | 2013-02-06 05:59:33 +0000 | [diff] [blame] | 11356 |         std::string InsertionText = std::string(" ") + RD->getKindName(); | 
| Richard Smith | 6b13022 | 2011-10-18 21:39:00 +0000 | [diff] [blame] | 11357 |        | 
| Nick Lewycky | ce6a10e | 2013-02-06 05:59:33 +0000 | [diff] [blame] | 11358 |         Diag(TypeRange.getBegin(), | 
 | 11359 |              getLangOpts().CPlusPlus11 ? | 
 | 11360 |                diag::warn_cxx98_compat_unelaborated_friend_type : | 
 | 11361 |                diag::ext_unelaborated_friend_type) | 
 | 11362 |           << (unsigned) RD->getTagKind() | 
 | 11363 |           << T | 
 | 11364 |           << FixItHint::CreateInsertion(PP.getLocForEndOfToken(FriendLoc), | 
 | 11365 |                                         InsertionText); | 
 | 11366 |       } else { | 
 | 11367 |         Diag(FriendLoc, | 
 | 11368 |              getLangOpts().CPlusPlus11 ? | 
 | 11369 |                diag::warn_cxx98_compat_nonclass_type_friend : | 
 | 11370 |                diag::ext_nonclass_type_friend) | 
 | 11371 |           << T | 
 | 11372 |           << TypeRange; | 
 | 11373 |       } | 
 | 11374 |     } else if (T->getAs<EnumType>()) { | 
| Richard Smith | 6b13022 | 2011-10-18 21:39:00 +0000 | [diff] [blame] | 11375 |       Diag(FriendLoc, | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 11376 |            getLangOpts().CPlusPlus11 ? | 
| Nick Lewycky | ce6a10e | 2013-02-06 05:59:33 +0000 | [diff] [blame] | 11377 |              diag::warn_cxx98_compat_enum_friend : | 
 | 11378 |              diag::ext_enum_friend) | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11379 |         << T | 
| Richard Smith | d6f80da | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 11380 |         << TypeRange; | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11381 |     } | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11382 |    | 
| Nick Lewycky | ce6a10e | 2013-02-06 05:59:33 +0000 | [diff] [blame] | 11383 |     // C++11 [class.friend]p3: | 
 | 11384 |     //   A friend declaration that does not declare a function shall have one | 
 | 11385 |     //   of the following forms: | 
 | 11386 |     //     friend elaborated-type-specifier ; | 
 | 11387 |     //     friend simple-type-specifier ; | 
 | 11388 |     //     friend typename-specifier ; | 
 | 11389 |     if (getLangOpts().CPlusPlus11 && LocStart != FriendLoc) | 
 | 11390 |       Diag(FriendLoc, diag::err_friend_not_first_in_declaration) << T; | 
 | 11391 |   } | 
| Richard Smith | d6f80da | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 11392 |  | 
| Douglas Gregor | 06245bf | 2010-04-07 17:57:12 +0000 | [diff] [blame] | 11393 |   //   If the type specifier in a friend declaration designates a (possibly | 
| Richard Smith | d6f80da | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 11394 |   //   cv-qualified) class type, that class is declared as a friend; otherwise, | 
| Douglas Gregor | 06245bf | 2010-04-07 17:57:12 +0000 | [diff] [blame] | 11395 |   //   the friend declaration is ignored. | 
| Richard Smith | d6f80da | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 11396 |   return FriendDecl::Create(Context, CurContext, LocStart, TSInfo, FriendLoc); | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11397 | } | 
 | 11398 |  | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11399 | /// Handle a friend tag declaration where the scope specifier was | 
 | 11400 | /// templated. | 
 | 11401 | Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, | 
 | 11402 |                                     unsigned TagSpec, SourceLocation TagLoc, | 
 | 11403 |                                     CXXScopeSpec &SS, | 
| Enea Zaffanella | 8c84028 | 2013-01-31 09:54:08 +0000 | [diff] [blame] | 11404 |                                     IdentifierInfo *Name, | 
 | 11405 |                                     SourceLocation NameLoc, | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11406 |                                     AttributeList *Attr, | 
 | 11407 |                                     MultiTemplateParamsArg TempParamLists) { | 
 | 11408 |   TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); | 
 | 11409 |  | 
 | 11410 |   bool isExplicitSpecialization = false; | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11411 |   bool Invalid = false; | 
 | 11412 |  | 
| Robert Wilhelm | 1169e2f | 2013-07-21 15:20:44 +0000 | [diff] [blame] | 11413 |   if (TemplateParameterList *TemplateParams = | 
 | 11414 |           MatchTemplateParametersToScopeSpecifier( | 
 | 11415 |               TagLoc, NameLoc, SS, TempParamLists, /*friend*/ true, | 
 | 11416 |               isExplicitSpecialization, Invalid)) { | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11417 |     if (TemplateParams->size() > 0) { | 
 | 11418 |       // This is a declaration of a class template. | 
 | 11419 |       if (Invalid) | 
 | 11420 |         return 0; | 
| Abramo Bagnara | c57c17d | 2011-03-10 13:28:31 +0000 | [diff] [blame] | 11421 |  | 
| Eric Christopher | 4110e13 | 2011-07-21 05:34:24 +0000 | [diff] [blame] | 11422 |       return CheckClassTemplate(S, TagSpec, TUK_Friend, TagLoc, | 
 | 11423 |                                 SS, Name, NameLoc, Attr, | 
 | 11424 |                                 TemplateParams, AS_public, | 
| Douglas Gregor | e761230 | 2011-09-09 19:05:14 +0000 | [diff] [blame] | 11425 |                                 /*ModulePrivateLoc=*/SourceLocation(), | 
| Eric Christopher | 4110e13 | 2011-07-21 05:34:24 +0000 | [diff] [blame] | 11426 |                                 TempParamLists.size() - 1, | 
| Benjamin Kramer | 5354e77 | 2012-08-23 23:38:35 +0000 | [diff] [blame] | 11427 |                                 TempParamLists.data()).take(); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11428 |     } else { | 
 | 11429 |       // The "template<>" header is extraneous. | 
 | 11430 |       Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams) | 
 | 11431 |         << TypeWithKeyword::getTagTypeKindName(Kind) << Name; | 
 | 11432 |       isExplicitSpecialization = true; | 
 | 11433 |     } | 
 | 11434 |   } | 
 | 11435 |  | 
 | 11436 |   if (Invalid) return 0; | 
 | 11437 |  | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11438 |   bool isAllExplicitSpecializations = true; | 
| Abramo Bagnara | 7f0a915 | 2011-03-18 15:16:37 +0000 | [diff] [blame] | 11439 |   for (unsigned I = TempParamLists.size(); I-- > 0; ) { | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 11440 |     if (TempParamLists[I]->size()) { | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11441 |       isAllExplicitSpecializations = false; | 
 | 11442 |       break; | 
 | 11443 |     } | 
 | 11444 |   } | 
 | 11445 |  | 
 | 11446 |   // FIXME: don't ignore attributes. | 
 | 11447 |  | 
 | 11448 |   // If it's explicit specializations all the way down, just forget | 
 | 11449 |   // about the template header and build an appropriate non-templated | 
 | 11450 |   // friend.  TODO: for source fidelity, remember the headers. | 
 | 11451 |   if (isAllExplicitSpecializations) { | 
| Douglas Gregor | ba4ee9a | 2011-10-20 15:58:54 +0000 | [diff] [blame] | 11452 |     if (SS.isEmpty()) { | 
 | 11453 |       bool Owned = false; | 
 | 11454 |       bool IsDependent = false; | 
 | 11455 |       return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, | 
 | 11456 |                       Attr, AS_public,  | 
 | 11457 |                       /*ModulePrivateLoc=*/SourceLocation(), | 
 | 11458 |                       MultiTemplateParamsArg(), Owned, IsDependent,  | 
| Richard Smith | bdad7a2 | 2012-01-10 01:33:14 +0000 | [diff] [blame] | 11459 |                       /*ScopedEnumKWLoc=*/SourceLocation(), | 
| Douglas Gregor | ba4ee9a | 2011-10-20 15:58:54 +0000 | [diff] [blame] | 11460 |                       /*ScopedEnumUsesClassTag=*/false, | 
 | 11461 |                       /*UnderlyingType=*/TypeResult());           | 
 | 11462 |     } | 
 | 11463 |      | 
| Douglas Gregor | 2494dd0 | 2011-03-01 01:34:45 +0000 | [diff] [blame] | 11464 |     NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11465 |     ElaboratedTypeKeyword Keyword | 
 | 11466 |       = TypeWithKeyword::getKeywordForTagTypeKind(Kind); | 
| Douglas Gregor | 2494dd0 | 2011-03-01 01:34:45 +0000 | [diff] [blame] | 11467 |     QualType T = CheckTypenameType(Keyword, TagLoc, QualifierLoc, | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 11468 |                                    *Name, NameLoc); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11469 |     if (T.isNull()) | 
 | 11470 |       return 0; | 
 | 11471 |  | 
 | 11472 |     TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); | 
 | 11473 |     if (isa<DependentNameType>(T)) { | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 11474 |       DependentNameTypeLoc TL = | 
 | 11475 |           TSI->getTypeLoc().castAs<DependentNameTypeLoc>(); | 
| Abramo Bagnara | 38a4291 | 2012-02-06 19:09:27 +0000 | [diff] [blame] | 11476 |       TL.setElaboratedKeywordLoc(TagLoc); | 
| Douglas Gregor | 2494dd0 | 2011-03-01 01:34:45 +0000 | [diff] [blame] | 11477 |       TL.setQualifierLoc(QualifierLoc); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11478 |       TL.setNameLoc(NameLoc); | 
 | 11479 |     } else { | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 11480 |       ElaboratedTypeLoc TL = TSI->getTypeLoc().castAs<ElaboratedTypeLoc>(); | 
| Abramo Bagnara | 38a4291 | 2012-02-06 19:09:27 +0000 | [diff] [blame] | 11481 |       TL.setElaboratedKeywordLoc(TagLoc); | 
| Douglas Gregor | 9e87687 | 2011-03-01 18:12:44 +0000 | [diff] [blame] | 11482 |       TL.setQualifierLoc(QualifierLoc); | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 11483 |       TL.getNamedTypeLoc().castAs<TypeSpecTypeLoc>().setNameLoc(NameLoc); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11484 |     } | 
 | 11485 |  | 
 | 11486 |     FriendDecl *Friend = FriendDecl::Create(Context, CurContext, NameLoc, | 
| Enea Zaffanella | 8c84028 | 2013-01-31 09:54:08 +0000 | [diff] [blame] | 11487 |                                             TSI, FriendLoc, TempParamLists); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11488 |     Friend->setAccess(AS_public); | 
 | 11489 |     CurContext->addDecl(Friend); | 
 | 11490 |     return Friend; | 
 | 11491 |   } | 
| Douglas Gregor | ba4ee9a | 2011-10-20 15:58:54 +0000 | [diff] [blame] | 11492 |    | 
 | 11493 |   assert(SS.isNotEmpty() && "valid templated tag with no SS and no direct?"); | 
 | 11494 |    | 
 | 11495 |  | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11496 |  | 
 | 11497 |   // Handle the case of a templated-scope friend class.  e.g. | 
 | 11498 |   //   template <class T> class A<T>::B; | 
 | 11499 |   // FIXME: we don't support these right now. | 
 | 11500 |   ElaboratedTypeKeyword ETK = TypeWithKeyword::getKeywordForTagTypeKind(Kind); | 
 | 11501 |   QualType T = Context.getDependentNameType(ETK, SS.getScopeRep(), Name); | 
 | 11502 |   TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 11503 |   DependentNameTypeLoc TL = TSI->getTypeLoc().castAs<DependentNameTypeLoc>(); | 
| Abramo Bagnara | 38a4291 | 2012-02-06 19:09:27 +0000 | [diff] [blame] | 11504 |   TL.setElaboratedKeywordLoc(TagLoc); | 
| Douglas Gregor | 2494dd0 | 2011-03-01 01:34:45 +0000 | [diff] [blame] | 11505 |   TL.setQualifierLoc(SS.getWithLocInContext(Context)); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11506 |   TL.setNameLoc(NameLoc); | 
 | 11507 |  | 
 | 11508 |   FriendDecl *Friend = FriendDecl::Create(Context, CurContext, NameLoc, | 
| Enea Zaffanella | 8c84028 | 2013-01-31 09:54:08 +0000 | [diff] [blame] | 11509 |                                           TSI, FriendLoc, TempParamLists); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 11510 |   Friend->setAccess(AS_public); | 
 | 11511 |   Friend->setUnsupportedFriend(true); | 
 | 11512 |   CurContext->addDecl(Friend); | 
 | 11513 |   return Friend; | 
 | 11514 | } | 
 | 11515 |  | 
 | 11516 |  | 
| John McCall | dd4a3b0 | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 11517 | /// Handle a friend type declaration.  This works in tandem with | 
 | 11518 | /// ActOnTag. | 
 | 11519 | /// | 
 | 11520 | /// Notes on friend class templates: | 
 | 11521 | /// | 
 | 11522 | /// We generally treat friend class declarations as if they were | 
 | 11523 | /// declaring a class.  So, for example, the elaborated type specifier | 
 | 11524 | /// in a friend declaration is required to obey the restrictions of a | 
 | 11525 | /// class-head (i.e. no typedefs in the scope chain), template | 
 | 11526 | /// parameters are required to match up with simple template-ids, &c. | 
 | 11527 | /// However, unlike when declaring a template specialization, it's | 
 | 11528 | /// okay to refer to a template specialization without an empty | 
 | 11529 | /// template parameter declaration, e.g. | 
 | 11530 | ///   friend class A<T>::B<unsigned>; | 
 | 11531 | /// We permit this as a special case; if there are any template | 
 | 11532 | /// parameters present at all, require proper matching, i.e. | 
| James Dennett | ef2b5b3 | 2012-06-15 22:23:43 +0000 | [diff] [blame] | 11533 | ///   template <> template \<class T> friend class A<int>::B; | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11534 | Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS, | 
| John McCall | be04b6d | 2010-10-16 07:23:36 +0000 | [diff] [blame] | 11535 |                                 MultiTemplateParamsArg TempParams) { | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 11536 |   SourceLocation Loc = DS.getLocStart(); | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11537 |  | 
 | 11538 |   assert(DS.isFriendSpecified()); | 
 | 11539 |   assert(DS.getStorageClassSpec() == DeclSpec::SCS_unspecified); | 
 | 11540 |  | 
| John McCall | dd4a3b0 | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 11541 |   // Try to convert the decl specifier to a type.  This works for | 
 | 11542 |   // friend templates because ActOnTag never produces a ClassTemplateDecl | 
 | 11543 |   // for a TUK_Friend. | 
| Chris Lattner | c7f1904 | 2009-10-25 17:47:27 +0000 | [diff] [blame] | 11544 |   Declarator TheDeclarator(DS, Declarator::MemberContext); | 
| John McCall | bf1a028 | 2010-06-04 23:28:52 +0000 | [diff] [blame] | 11545 |   TypeSourceInfo *TSI = GetTypeForDeclarator(TheDeclarator, S); | 
 | 11546 |   QualType T = TSI->getType(); | 
| Chris Lattner | c7f1904 | 2009-10-25 17:47:27 +0000 | [diff] [blame] | 11547 |   if (TheDeclarator.isInvalidType()) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11548 |     return 0; | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11549 |  | 
| Douglas Gregor | 6ccab97 | 2010-12-16 01:14:37 +0000 | [diff] [blame] | 11550 |   if (DiagnoseUnexpandedParameterPack(Loc, TSI, UPPC_FriendDeclaration)) | 
 | 11551 |     return 0; | 
 | 11552 |  | 
| John McCall | dd4a3b0 | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 11553 |   // This is definitely an error in C++98.  It's probably meant to | 
 | 11554 |   // be forbidden in C++0x, too, but the specification is just | 
 | 11555 |   // poorly written. | 
 | 11556 |   // | 
 | 11557 |   // The problem is with declarations like the following: | 
 | 11558 |   //   template <T> friend A<T>::foo; | 
 | 11559 |   // where deciding whether a class C is a friend or not now hinges | 
 | 11560 |   // on whether there exists an instantiation of A that causes | 
 | 11561 |   // 'foo' to equal C.  There are restrictions on class-heads | 
 | 11562 |   // (which we declare (by fiat) elaborated friend declarations to | 
 | 11563 |   // be) that makes this tractable. | 
 | 11564 |   // | 
 | 11565 |   // FIXME: handle "template <> friend class A<T>;", which | 
 | 11566 |   // is possibly well-formed?  Who even knows? | 
| Douglas Gregor | 4033642 | 2010-03-31 22:19:08 +0000 | [diff] [blame] | 11567 |   if (TempParams.size() && !T->isElaboratedTypeSpecifier()) { | 
| John McCall | dd4a3b0 | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 11568 |     Diag(Loc, diag::err_tagless_friend_type_template) | 
 | 11569 |       << DS.getSourceRange(); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11570 |     return 0; | 
| John McCall | dd4a3b0 | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 11571 |   } | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11572 |    | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 11573 |   // C++98 [class.friend]p1: A friend of a class is a function | 
 | 11574 |   //   or class that is not a member of the class . . . | 
| John McCall | a236a55 | 2009-12-22 00:59:39 +0000 | [diff] [blame] | 11575 |   // This is fixed in DR77, which just barely didn't make the C++03 | 
 | 11576 |   // deadline.  It's also a very silly restriction that seriously | 
 | 11577 |   // affects inner classes and which nobody else seems to implement; | 
 | 11578 |   // thus we never diagnose it, not even in -pedantic. | 
| John McCall | 32f2fb5 | 2010-03-25 18:04:51 +0000 | [diff] [blame] | 11579 |   // | 
 | 11580 |   // But note that we could warn about it: it's always useless to | 
 | 11581 |   // friend one of your own members (it's not, however, worthless to | 
 | 11582 |   // friend a member of an arbitrary specialization of your template). | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 11583 |  | 
| John McCall | dd4a3b0 | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 11584 |   Decl *D; | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11585 |   if (unsigned NumTempParamLists = TempParams.size()) | 
| John McCall | dd4a3b0 | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 11586 |     D = FriendTemplateDecl::Create(Context, CurContext, Loc, | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11587 |                                    NumTempParamLists, | 
| Benjamin Kramer | 5354e77 | 2012-08-23 23:38:35 +0000 | [diff] [blame] | 11588 |                                    TempParams.data(), | 
| John McCall | 32f2fb5 | 2010-03-25 18:04:51 +0000 | [diff] [blame] | 11589 |                                    TSI, | 
| John McCall | dd4a3b0 | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 11590 |                                    DS.getFriendSpecLoc()); | 
 | 11591 |   else | 
| Abramo Bagnara | 0216df8 | 2011-10-29 20:52:52 +0000 | [diff] [blame] | 11592 |     D = CheckFriendTypeDecl(Loc, DS.getFriendSpecLoc(), TSI); | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11593 |    | 
 | 11594 |   if (!D) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11595 |     return 0; | 
| Douglas Gregor | 1d86935 | 2010-04-07 16:53:43 +0000 | [diff] [blame] | 11596 |    | 
| John McCall | dd4a3b0 | 2009-09-16 22:47:08 +0000 | [diff] [blame] | 11597 |   D->setAccess(AS_public); | 
 | 11598 |   CurContext->addDecl(D); | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 11599 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11600 |   return D; | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 11601 | } | 
 | 11602 |  | 
| Rafael Espindola | fc35cbc | 2013-01-08 20:44:06 +0000 | [diff] [blame] | 11603 | NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D, | 
 | 11604 |                                         MultiTemplateParamsArg TemplateParams) { | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 11605 |   const DeclSpec &DS = D.getDeclSpec(); | 
 | 11606 |  | 
 | 11607 |   assert(DS.isFriendSpecified()); | 
 | 11608 |   assert(DS.getStorageClassSpec() == DeclSpec::SCS_unspecified); | 
 | 11609 |  | 
 | 11610 |   SourceLocation Loc = D.getIdentifierLoc(); | 
| John McCall | bf1a028 | 2010-06-04 23:28:52 +0000 | [diff] [blame] | 11611 |   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11612 |  | 
 | 11613 |   // C++ [class.friend]p1 | 
 | 11614 |   //   A friend of a class is a function or class.... | 
 | 11615 |   // Note that this sees through typedefs, which is intended. | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 11616 |   // It *doesn't* see through dependent types, which is correct | 
 | 11617 |   // according to [temp.arg.type]p3: | 
 | 11618 |   //   If a declaration acquires a function type through a | 
 | 11619 |   //   type dependent on a template-parameter and this causes | 
 | 11620 |   //   a declaration that does not use the syntactic form of a | 
 | 11621 |   //   function declarator to have a function type, the program | 
 | 11622 |   //   is ill-formed. | 
| Kaelyn Uhrain | 2c712f5 | 2011-10-11 00:28:45 +0000 | [diff] [blame] | 11623 |   if (!TInfo->getType()->isFunctionType()) { | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11624 |     Diag(Loc, diag::err_unexpected_friend); | 
 | 11625 |  | 
 | 11626 |     // It might be worthwhile to try to recover by creating an | 
 | 11627 |     // appropriate declaration. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11628 |     return 0; | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11629 |   } | 
 | 11630 |  | 
 | 11631 |   // C++ [namespace.memdef]p3 | 
 | 11632 |   //  - If a friend declaration in a non-local class first declares a | 
 | 11633 |   //    class or function, the friend class or function is a member | 
 | 11634 |   //    of the innermost enclosing namespace. | 
 | 11635 |   //  - The name of the friend is not found by simple name lookup | 
 | 11636 |   //    until a matching declaration is provided in that namespace | 
 | 11637 |   //    scope (either before or after the class declaration granting | 
 | 11638 |   //    friendship). | 
 | 11639 |   //  - If a friend function is called, its name may be found by the | 
 | 11640 |   //    name lookup that considers functions from namespaces and | 
 | 11641 |   //    classes associated with the types of the function arguments. | 
 | 11642 |   //  - When looking for a prior declaration of a class or a function | 
 | 11643 |   //    declared as a friend, scopes outside the innermost enclosing | 
 | 11644 |   //    namespace scope are not considered. | 
 | 11645 |  | 
| John McCall | 337ec3d | 2010-10-12 23:13:28 +0000 | [diff] [blame] | 11646 |   CXXScopeSpec &SS = D.getCXXScopeSpec(); | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 11647 |   DeclarationNameInfo NameInfo = GetNameForDeclarator(D); | 
 | 11648 |   DeclarationName Name = NameInfo.getName(); | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11649 |   assert(Name); | 
 | 11650 |  | 
| Douglas Gregor | 6ccab97 | 2010-12-16 01:14:37 +0000 | [diff] [blame] | 11651 |   // Check for unexpanded parameter packs. | 
 | 11652 |   if (DiagnoseUnexpandedParameterPack(Loc, TInfo, UPPC_FriendDeclaration) || | 
 | 11653 |       DiagnoseUnexpandedParameterPack(NameInfo, UPPC_FriendDeclaration) || | 
 | 11654 |       DiagnoseUnexpandedParameterPack(SS, UPPC_FriendDeclaration)) | 
 | 11655 |     return 0; | 
 | 11656 |  | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11657 |   // The context we found the declaration in, or in which we should | 
 | 11658 |   // create the declaration. | 
 | 11659 |   DeclContext *DC; | 
| John McCall | 380aaa4 | 2010-10-13 06:22:15 +0000 | [diff] [blame] | 11660 |   Scope *DCScope = S; | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 11661 |   LookupResult Previous(*this, NameInfo, LookupOrdinaryName, | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 11662 |                         ForRedeclaration); | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11663 |  | 
| Richard Smith | 4e9686b | 2013-08-09 04:35:01 +0000 | [diff] [blame] | 11664 |   // There are five cases here. | 
 | 11665 |   //   - There's no scope specifier and we're in a local class. Only look | 
 | 11666 |   //     for functions declared in the immediately-enclosing block scope. | 
 | 11667 |   // We recover from invalid scope qualifiers as if they just weren't there. | 
 | 11668 |   FunctionDecl *FunctionContainingLocalClass = 0; | 
 | 11669 |   if ((SS.isInvalid() || !SS.isSet()) && | 
 | 11670 |       (FunctionContainingLocalClass = | 
 | 11671 |            cast<CXXRecordDecl>(CurContext)->isLocalClass())) { | 
 | 11672 |     // C++11 [class.friend]p11: | 
| John McCall | 29ae6e5 | 2010-10-13 05:45:15 +0000 | [diff] [blame] | 11673 |     //   If a friend declaration appears in a local class and the name | 
 | 11674 |     //   specified is an unqualified name, a prior declaration is | 
 | 11675 |     //   looked up without considering scopes that are outside the | 
 | 11676 |     //   innermost enclosing non-class scope. For a friend function | 
 | 11677 |     //   declaration, if there is no prior declaration, the program is | 
 | 11678 |     //   ill-formed. | 
| Richard Smith | 4e9686b | 2013-08-09 04:35:01 +0000 | [diff] [blame] | 11679 |  | 
 | 11680 |     // Find the innermost enclosing non-class scope. This is the block | 
 | 11681 |     // scope containing the local class definition (or for a nested class, | 
 | 11682 |     // the outer local class). | 
 | 11683 |     DCScope = S->getFnParent(); | 
 | 11684 |  | 
 | 11685 |     // Look up the function name in the scope. | 
 | 11686 |     Previous.clear(LookupLocalFriendName); | 
 | 11687 |     LookupName(Previous, S, /*AllowBuiltinCreation*/false); | 
 | 11688 |  | 
 | 11689 |     if (!Previous.empty()) { | 
 | 11690 |       // All possible previous declarations must have the same context: | 
 | 11691 |       // either they were declared at block scope or they are members of | 
 | 11692 |       // one of the enclosing local classes. | 
 | 11693 |       DC = Previous.getRepresentativeDecl()->getDeclContext(); | 
 | 11694 |     } else { | 
 | 11695 |       // This is ill-formed, but provide the context that we would have | 
 | 11696 |       // declared the function in, if we were permitted to, for error recovery. | 
 | 11697 |       DC = FunctionContainingLocalClass; | 
 | 11698 |     } | 
| Richard Smith | a41c97a | 2013-09-20 01:15:31 +0000 | [diff] [blame] | 11699 |     adjustContextForLocalExternDecl(DC); | 
| Richard Smith | 4e9686b | 2013-08-09 04:35:01 +0000 | [diff] [blame] | 11700 |  | 
 | 11701 |     // C++ [class.friend]p6: | 
 | 11702 |     //   A function can be defined in a friend declaration of a class if and | 
 | 11703 |     //   only if the class is a non-local class (9.8), the function name is | 
 | 11704 |     //   unqualified, and the function has namespace scope. | 
 | 11705 |     if (D.isFunctionDefinition()) { | 
 | 11706 |       Diag(NameInfo.getBeginLoc(), diag::err_friend_def_in_local_class); | 
 | 11707 |     } | 
 | 11708 |  | 
 | 11709 |   //   - There's no scope specifier, in which case we just go to the | 
 | 11710 |   //     appropriate scope and look for a function or function template | 
 | 11711 |   //     there as appropriate. | 
 | 11712 |   } else if (SS.isInvalid() || !SS.isSet()) { | 
 | 11713 |     // C++11 [namespace.memdef]p3: | 
 | 11714 |     //   If the name in a friend declaration is neither qualified nor | 
 | 11715 |     //   a template-id and the declaration is a function or an | 
 | 11716 |     //   elaborated-type-specifier, the lookup to determine whether | 
 | 11717 |     //   the entity has been previously declared shall not consider | 
 | 11718 |     //   any scopes outside the innermost enclosing namespace. | 
| John McCall | 8a40737 | 2010-10-14 22:22:28 +0000 | [diff] [blame] | 11719 |     bool isTemplateId = D.getName().getKind() == UnqualifiedId::IK_TemplateId; | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11720 |  | 
| John McCall | 29ae6e5 | 2010-10-13 05:45:15 +0000 | [diff] [blame] | 11721 |     // Find the appropriate context according to the above. | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11722 |     DC = CurContext; | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11723 |  | 
| Rafael Espindola | 11dc634 | 2013-04-25 20:12:36 +0000 | [diff] [blame] | 11724 |     // Skip class contexts.  If someone can cite chapter and verse | 
 | 11725 |     // for this behavior, that would be nice --- it's what GCC and | 
 | 11726 |     // EDG do, and it seems like a reasonable intent, but the spec | 
 | 11727 |     // really only says that checks for unqualified existing | 
 | 11728 |     // declarations should stop at the nearest enclosing namespace, | 
 | 11729 |     // not that they should only consider the nearest enclosing | 
 | 11730 |     // namespace. | 
 | 11731 |     while (DC->isRecord()) | 
 | 11732 |       DC = DC->getParent(); | 
 | 11733 |  | 
 | 11734 |     DeclContext *LookupDC = DC; | 
 | 11735 |     while (LookupDC->isTransparentContext()) | 
 | 11736 |       LookupDC = LookupDC->getParent(); | 
 | 11737 |  | 
 | 11738 |     while (true) { | 
 | 11739 |       LookupQualifiedName(Previous, LookupDC); | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11740 |  | 
| Rafael Espindola | 11dc634 | 2013-04-25 20:12:36 +0000 | [diff] [blame] | 11741 |       if (!Previous.empty()) { | 
 | 11742 |         DC = LookupDC; | 
 | 11743 |         break; | 
| John McCall | 8a40737 | 2010-10-14 22:22:28 +0000 | [diff] [blame] | 11744 |       } | 
| Rafael Espindola | 11dc634 | 2013-04-25 20:12:36 +0000 | [diff] [blame] | 11745 |  | 
 | 11746 |       if (isTemplateId) { | 
 | 11747 |         if (isa<TranslationUnitDecl>(LookupDC)) break; | 
 | 11748 |       } else { | 
 | 11749 |         if (LookupDC->isFileContext()) break; | 
 | 11750 |       } | 
 | 11751 |       LookupDC = LookupDC->getParent(); | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11752 |     } | 
 | 11753 |  | 
| John McCall | 380aaa4 | 2010-10-13 06:22:15 +0000 | [diff] [blame] | 11754 |     DCScope = getScopeForDeclContext(S, DC); | 
| Richard Smith | 4e9686b | 2013-08-09 04:35:01 +0000 | [diff] [blame] | 11755 |  | 
| John McCall | 337ec3d | 2010-10-12 23:13:28 +0000 | [diff] [blame] | 11756 |   //   - There's a non-dependent scope specifier, in which case we | 
 | 11757 |   //     compute it and do a previous lookup there for a function | 
 | 11758 |   //     or function template. | 
 | 11759 |   } else if (!SS.getScopeRep()->isDependent()) { | 
 | 11760 |     DC = computeDeclContext(SS); | 
 | 11761 |     if (!DC) return 0; | 
 | 11762 |  | 
 | 11763 |     if (RequireCompleteDeclContext(SS, DC)) return 0; | 
 | 11764 |  | 
 | 11765 |     LookupQualifiedName(Previous, DC); | 
 | 11766 |  | 
 | 11767 |     // Ignore things found implicitly in the wrong scope. | 
 | 11768 |     // TODO: better diagnostics for this case.  Suggesting the right | 
 | 11769 |     // qualified scope would be nice... | 
 | 11770 |     LookupResult::Filter F = Previous.makeFilter(); | 
 | 11771 |     while (F.hasNext()) { | 
 | 11772 |       NamedDecl *D = F.next(); | 
 | 11773 |       if (!DC->InEnclosingNamespaceSetOf( | 
 | 11774 |               D->getDeclContext()->getRedeclContext())) | 
 | 11775 |         F.erase(); | 
 | 11776 |     } | 
 | 11777 |     F.done(); | 
 | 11778 |  | 
 | 11779 |     if (Previous.empty()) { | 
 | 11780 |       D.setInvalidType(); | 
| Kaelyn Uhrain | 2c712f5 | 2011-10-11 00:28:45 +0000 | [diff] [blame] | 11781 |       Diag(Loc, diag::err_qualified_friend_not_found) | 
 | 11782 |           << Name << TInfo->getType(); | 
| John McCall | 337ec3d | 2010-10-12 23:13:28 +0000 | [diff] [blame] | 11783 |       return 0; | 
 | 11784 |     } | 
 | 11785 |  | 
 | 11786 |     // C++ [class.friend]p1: A friend of a class is a function or | 
 | 11787 |     //   class that is not a member of the class . . . | 
| Richard Smith | ebaf0e6 | 2011-10-18 20:49:44 +0000 | [diff] [blame] | 11788 |     if (DC->Equals(CurContext)) | 
 | 11789 |       Diag(DS.getFriendSpecLoc(), | 
| Richard Smith | 80ad52f | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 11790 |            getLangOpts().CPlusPlus11 ? | 
| Richard Smith | ebaf0e6 | 2011-10-18 20:49:44 +0000 | [diff] [blame] | 11791 |              diag::warn_cxx98_compat_friend_is_member : | 
 | 11792 |              diag::err_friend_is_member); | 
| Douglas Gregor | 883af83 | 2011-10-10 01:11:59 +0000 | [diff] [blame] | 11793 |      | 
| Kaelyn Uhrain | 2c712f5 | 2011-10-11 00:28:45 +0000 | [diff] [blame] | 11794 |     if (D.isFunctionDefinition()) { | 
| Douglas Gregor | 883af83 | 2011-10-10 01:11:59 +0000 | [diff] [blame] | 11795 |       // C++ [class.friend]p6: | 
 | 11796 |       //   A function can be defined in a friend declaration of a class if and  | 
 | 11797 |       //   only if the class is a non-local class (9.8), the function name is | 
 | 11798 |       //   unqualified, and the function has namespace scope. | 
 | 11799 |       SemaDiagnosticBuilder DB | 
 | 11800 |         = Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def); | 
 | 11801 |        | 
 | 11802 |       DB << SS.getScopeRep(); | 
 | 11803 |       if (DC->isFileContext()) | 
 | 11804 |         DB << FixItHint::CreateRemoval(SS.getRange()); | 
 | 11805 |       SS.clear(); | 
 | 11806 |     } | 
| John McCall | 337ec3d | 2010-10-12 23:13:28 +0000 | [diff] [blame] | 11807 |  | 
 | 11808 |   //   - There's a scope specifier that does not match any template | 
 | 11809 |   //     parameter lists, in which case we use some arbitrary context, | 
 | 11810 |   //     create a method or method template, and wait for instantiation. | 
 | 11811 |   //   - There's a scope specifier that does match some template | 
 | 11812 |   //     parameter lists, which we don't handle right now. | 
 | 11813 |   } else { | 
| Kaelyn Uhrain | 2c712f5 | 2011-10-11 00:28:45 +0000 | [diff] [blame] | 11814 |     if (D.isFunctionDefinition()) { | 
| Douglas Gregor | 883af83 | 2011-10-10 01:11:59 +0000 | [diff] [blame] | 11815 |       // C++ [class.friend]p6: | 
 | 11816 |       //   A function can be defined in a friend declaration of a class if and  | 
 | 11817 |       //   only if the class is a non-local class (9.8), the function name is | 
 | 11818 |       //   unqualified, and the function has namespace scope. | 
 | 11819 |       Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def) | 
 | 11820 |         << SS.getScopeRep(); | 
 | 11821 |     } | 
 | 11822 |      | 
| John McCall | 337ec3d | 2010-10-12 23:13:28 +0000 | [diff] [blame] | 11823 |     DC = CurContext; | 
 | 11824 |     assert(isa<CXXRecordDecl>(DC) && "friend declaration not in class?"); | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11825 |   } | 
| Douglas Gregor | 883af83 | 2011-10-10 01:11:59 +0000 | [diff] [blame] | 11826 |    | 
| John McCall | 29ae6e5 | 2010-10-13 05:45:15 +0000 | [diff] [blame] | 11827 |   if (!DC->isRecord()) { | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11828 |     // This implies that it has to be an operator or function. | 
| Douglas Gregor | 3f9a056 | 2009-11-03 01:35:08 +0000 | [diff] [blame] | 11829 |     if (D.getName().getKind() == UnqualifiedId::IK_ConstructorName || | 
 | 11830 |         D.getName().getKind() == UnqualifiedId::IK_DestructorName || | 
 | 11831 |         D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId) { | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11832 |       Diag(Loc, diag::err_introducing_special_friend) << | 
| Douglas Gregor | 3f9a056 | 2009-11-03 01:35:08 +0000 | [diff] [blame] | 11833 |         (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 : | 
 | 11834 |          D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 : 2); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11835 |       return 0; | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11836 |     } | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11837 |   } | 
| Kaelyn Uhrain | 2c712f5 | 2011-10-11 00:28:45 +0000 | [diff] [blame] | 11838 |  | 
| Douglas Gregor | fb35e8f | 2011-11-03 16:37:14 +0000 | [diff] [blame] | 11839 |   // FIXME: This is an egregious hack to cope with cases where the scope stack | 
 | 11840 |   // does not contain the declaration context, i.e., in an out-of-line  | 
 | 11841 |   // definition of a class. | 
 | 11842 |   Scope FakeDCScope(S, Scope::DeclScope, Diags); | 
 | 11843 |   if (!DCScope) { | 
 | 11844 |     FakeDCScope.setEntity(DC); | 
 | 11845 |     DCScope = &FakeDCScope; | 
 | 11846 |   } | 
| Richard Smith | 4e9686b | 2013-08-09 04:35:01 +0000 | [diff] [blame] | 11847 |  | 
| Francois Pichet | af0f4d0 | 2011-08-14 03:52:19 +0000 | [diff] [blame] | 11848 |   bool AddToScope = true; | 
| Kaelyn Uhrain | 2c712f5 | 2011-10-11 00:28:45 +0000 | [diff] [blame] | 11849 |   NamedDecl *ND = ActOnFunctionDeclarator(DCScope, D, DC, TInfo, Previous, | 
| Benjamin Kramer | 3fe198b | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 11850 |                                           TemplateParams, AddToScope); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11851 |   if (!ND) return 0; | 
| John McCall | ab88d97 | 2009-08-31 22:39:49 +0000 | [diff] [blame] | 11852 |  | 
| Douglas Gregor | 182ddf0 | 2009-09-28 00:08:27 +0000 | [diff] [blame] | 11853 |   assert(ND->getLexicalDeclContext() == CurContext); | 
| John McCall | 88232aa | 2009-08-18 00:00:49 +0000 | [diff] [blame] | 11854 |  | 
| Richard Smith | 4e9686b | 2013-08-09 04:35:01 +0000 | [diff] [blame] | 11855 |   // If we performed typo correction, we might have added a scope specifier | 
 | 11856 |   // and changed the decl context. | 
 | 11857 |   DC = ND->getDeclContext(); | 
 | 11858 |  | 
| John McCall | ab88d97 | 2009-08-31 22:39:49 +0000 | [diff] [blame] | 11859 |   // Add the function declaration to the appropriate lookup tables, | 
 | 11860 |   // adjusting the redeclarations list as necessary.  We don't | 
 | 11861 |   // want to do this yet if the friending class is dependent. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11862 |   // | 
| John McCall | ab88d97 | 2009-08-31 22:39:49 +0000 | [diff] [blame] | 11863 |   // Also update the scope-based lookup if the target context's | 
 | 11864 |   // lookup context is in lexical scope. | 
 | 11865 |   if (!CurContext->isDependentContext()) { | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 11866 |     DC = DC->getRedeclContext(); | 
| Richard Smith | 1b7f9cb | 2012-03-13 03:12:56 +0000 | [diff] [blame] | 11867 |     DC->makeDeclVisibleInContext(ND); | 
| John McCall | ab88d97 | 2009-08-31 22:39:49 +0000 | [diff] [blame] | 11868 |     if (Scope *EnclosingScope = getScopeForDeclContext(S, DC)) | 
| Douglas Gregor | 182ddf0 | 2009-09-28 00:08:27 +0000 | [diff] [blame] | 11869 |       PushOnScopeChains(ND, EnclosingScope, /*AddToContext=*/ false); | 
| John McCall | ab88d97 | 2009-08-31 22:39:49 +0000 | [diff] [blame] | 11870 |   } | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 11871 |  | 
 | 11872 |   FriendDecl *FrD = FriendDecl::Create(Context, CurContext, | 
| Douglas Gregor | 182ddf0 | 2009-09-28 00:08:27 +0000 | [diff] [blame] | 11873 |                                        D.getIdentifierLoc(), ND, | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 11874 |                                        DS.getFriendSpecLoc()); | 
| John McCall | 5fee110 | 2009-08-29 03:50:18 +0000 | [diff] [blame] | 11875 |   FrD->setAccess(AS_public); | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 11876 |   CurContext->addDecl(FrD); | 
| John McCall | 67d1a67 | 2009-08-06 02:15:43 +0000 | [diff] [blame] | 11877 |  | 
| John McCall | 1f2e1a9 | 2012-08-10 03:15:35 +0000 | [diff] [blame] | 11878 |   if (ND->isInvalidDecl()) { | 
| John McCall | 337ec3d | 2010-10-12 23:13:28 +0000 | [diff] [blame] | 11879 |     FrD->setInvalidDecl(); | 
| John McCall | 1f2e1a9 | 2012-08-10 03:15:35 +0000 | [diff] [blame] | 11880 |   } else { | 
 | 11881 |     if (DC->isRecord()) CheckFriendAccess(ND); | 
 | 11882 |  | 
| John McCall | 6102ca1 | 2010-10-16 06:59:13 +0000 | [diff] [blame] | 11883 |     FunctionDecl *FD; | 
 | 11884 |     if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND)) | 
 | 11885 |       FD = FTD->getTemplatedDecl(); | 
 | 11886 |     else | 
 | 11887 |       FD = cast<FunctionDecl>(ND); | 
 | 11888 |  | 
| David Majnemer | f6a144f | 2013-06-25 23:09:30 +0000 | [diff] [blame] | 11889 |     // C++11 [dcl.fct.default]p4: If a friend declaration specifies a | 
 | 11890 |     // default argument expression, that declaration shall be a definition | 
 | 11891 |     // and shall be the only declaration of the function or function | 
 | 11892 |     // template in the translation unit. | 
 | 11893 |     if (functionDeclHasDefaultArgument(FD)) { | 
 | 11894 |       if (FunctionDecl *OldFD = FD->getPreviousDecl()) { | 
 | 11895 |         Diag(FD->getLocation(), diag::err_friend_decl_with_def_arg_redeclared); | 
 | 11896 |         Diag(OldFD->getLocation(), diag::note_previous_declaration); | 
 | 11897 |       } else if (!D.isFunctionDefinition()) | 
 | 11898 |         Diag(FD->getLocation(), diag::err_friend_decl_with_def_arg_must_be_def); | 
 | 11899 |     } | 
 | 11900 |  | 
| John McCall | 6102ca1 | 2010-10-16 06:59:13 +0000 | [diff] [blame] | 11901 |     // Mark templated-scope function declarations as unsupported. | 
 | 11902 |     if (FD->getNumTemplateParameterLists()) | 
 | 11903 |       FrD->setUnsupportedFriend(true); | 
 | 11904 |   } | 
| John McCall | 337ec3d | 2010-10-12 23:13:28 +0000 | [diff] [blame] | 11905 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11906 |   return ND; | 
| Anders Carlsson | 0033836 | 2009-05-11 22:55:49 +0000 | [diff] [blame] | 11907 | } | 
 | 11908 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 11909 | void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) { | 
 | 11910 |   AdjustDeclIfTemplate(Dcl); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 11911 |  | 
| Aaron Ballman | afb7ce3 | 2013-01-16 23:39:10 +0000 | [diff] [blame] | 11912 |   FunctionDecl *Fn = dyn_cast_or_null<FunctionDecl>(Dcl); | 
| Sebastian Redl | 50de12f | 2009-03-24 22:27:57 +0000 | [diff] [blame] | 11913 |   if (!Fn) { | 
 | 11914 |     Diag(DelLoc, diag::err_deleted_non_function); | 
 | 11915 |     return; | 
 | 11916 |   } | 
| Richard Smith | 0ab5b4c | 2013-04-02 19:38:47 +0000 | [diff] [blame] | 11917 |  | 
| Douglas Gregor | ef96ee0 | 2012-01-14 16:38:05 +0000 | [diff] [blame] | 11918 |   if (const FunctionDecl *Prev = Fn->getPreviousDecl()) { | 
| David Blaikie | d9cf826 | 2012-06-25 21:55:30 +0000 | [diff] [blame] | 11919 |     // Don't consider the implicit declaration we generate for explicit | 
 | 11920 |     // specializations. FIXME: Do not generate these implicit declarations. | 
| David Blaikie | 619ee6a | 2012-06-29 18:00:25 +0000 | [diff] [blame] | 11921 |     if ((Prev->getTemplateSpecializationKind() != TSK_ExplicitSpecialization | 
 | 11922 |         || Prev->getPreviousDecl()) && !Prev->isDefined()) { | 
| David Blaikie | d9cf826 | 2012-06-25 21:55:30 +0000 | [diff] [blame] | 11923 |       Diag(DelLoc, diag::err_deleted_decl_not_first); | 
 | 11924 |       Diag(Prev->getLocation(), diag::note_previous_declaration); | 
 | 11925 |     } | 
| Sebastian Redl | 50de12f | 2009-03-24 22:27:57 +0000 | [diff] [blame] | 11926 |     // If the declaration wasn't the first, we delete the function anyway for | 
 | 11927 |     // recovery. | 
| Richard Smith | 0ab5b4c | 2013-04-02 19:38:47 +0000 | [diff] [blame] | 11928 |     Fn = Fn->getCanonicalDecl(); | 
| Sebastian Redl | 50de12f | 2009-03-24 22:27:57 +0000 | [diff] [blame] | 11929 |   } | 
| Richard Smith | 0ab5b4c | 2013-04-02 19:38:47 +0000 | [diff] [blame] | 11930 |  | 
 | 11931 |   if (Fn->isDeleted()) | 
 | 11932 |     return; | 
 | 11933 |  | 
 | 11934 |   // See if we're deleting a function which is already known to override a | 
 | 11935 |   // non-deleted virtual function. | 
 | 11936 |   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn)) { | 
 | 11937 |     bool IssuedDiagnostic = false; | 
 | 11938 |     for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), | 
 | 11939 |                                         E = MD->end_overridden_methods(); | 
 | 11940 |          I != E; ++I) { | 
 | 11941 |       if (!(*MD->begin_overridden_methods())->isDeleted()) { | 
 | 11942 |         if (!IssuedDiagnostic) { | 
 | 11943 |           Diag(DelLoc, diag::err_deleted_override) << MD->getDeclName(); | 
 | 11944 |           IssuedDiagnostic = true; | 
 | 11945 |         } | 
 | 11946 |         Diag((*I)->getLocation(), diag::note_overridden_virtual_function); | 
 | 11947 |       } | 
 | 11948 |     } | 
 | 11949 |   } | 
 | 11950 |  | 
| Sean Hunt | 10620eb | 2011-05-06 20:44:56 +0000 | [diff] [blame] | 11951 |   Fn->setDeletedAsWritten(); | 
| Sebastian Redl | 50de12f | 2009-03-24 22:27:57 +0000 | [diff] [blame] | 11952 | } | 
| Sebastian Redl | 13e8854 | 2009-04-27 21:33:24 +0000 | [diff] [blame] | 11953 |  | 
| Sean Hunt | e4246a6 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 11954 | void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { | 
| Aaron Ballman | afb7ce3 | 2013-01-16 23:39:10 +0000 | [diff] [blame] | 11955 |   CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Dcl); | 
| Sean Hunt | e4246a6 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 11956 |  | 
 | 11957 |   if (MD) { | 
| Sean Hunt | eb88ae5 | 2011-05-23 21:07:59 +0000 | [diff] [blame] | 11958 |     if (MD->getParent()->isDependentType()) { | 
 | 11959 |       MD->setDefaulted(); | 
 | 11960 |       MD->setExplicitlyDefaulted(); | 
 | 11961 |       return; | 
 | 11962 |     } | 
 | 11963 |  | 
| Sean Hunt | e4246a6 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 11964 |     CXXSpecialMember Member = getSpecialMember(MD); | 
 | 11965 |     if (Member == CXXInvalid) { | 
| Eli Friedman | fcb5a25 | 2013-07-11 23:55:07 +0000 | [diff] [blame] | 11966 |       if (!MD->isInvalidDecl()) | 
 | 11967 |         Diag(DefaultLoc, diag::err_default_special_members); | 
| Sean Hunt | e4246a6 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 11968 |       return; | 
 | 11969 |     } | 
 | 11970 |  | 
 | 11971 |     MD->setDefaulted(); | 
 | 11972 |     MD->setExplicitlyDefaulted(); | 
 | 11973 |  | 
| Sean Hunt | cd10dec | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 11974 |     // If this definition appears within the record, do the checking when | 
 | 11975 |     // the record is complete. | 
 | 11976 |     const FunctionDecl *Primary = MD; | 
| Richard Smith | a8eaf00 | 2012-08-23 06:16:52 +0000 | [diff] [blame] | 11977 |     if (const FunctionDecl *Pattern = MD->getTemplateInstantiationPattern()) | 
| Sean Hunt | cd10dec | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 11978 |       // Find the uninstantiated declaration that actually had the '= default' | 
 | 11979 |       // on it. | 
| Richard Smith | a8eaf00 | 2012-08-23 06:16:52 +0000 | [diff] [blame] | 11980 |       Pattern->isDefined(Primary); | 
| Sean Hunt | cd10dec | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 11981 |  | 
| Richard Smith | 12fef49 | 2013-03-27 00:22:47 +0000 | [diff] [blame] | 11982 |     // If the method was defaulted on its first declaration, we will have | 
 | 11983 |     // already performed the checking in CheckCompletedCXXClass. Such a | 
 | 11984 |     // declaration doesn't trigger an implicit definition. | 
| Sean Hunt | cd10dec | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 11985 |     if (Primary == Primary->getCanonicalDecl()) | 
| Sean Hunt | e4246a6 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 11986 |       return; | 
 | 11987 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 11988 |     CheckExplicitlyDefaultedSpecialMember(MD); | 
 | 11989 |  | 
| Richard Smith | 1d28caf | 2012-12-11 01:14:52 +0000 | [diff] [blame] | 11990 |     // The exception specification is needed because we are defining the | 
 | 11991 |     // function. | 
 | 11992 |     ResolveExceptionSpec(DefaultLoc, | 
 | 11993 |                          MD->getType()->castAs<FunctionProtoType>()); | 
 | 11994 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 11995 |     if (MD->isInvalidDecl()) | 
 | 11996 |       return; | 
 | 11997 |  | 
| Sean Hunt | e4246a6 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 11998 |     switch (Member) { | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 11999 |     case CXXDefaultConstructor: | 
 | 12000 |       DefineImplicitDefaultConstructor(DefaultLoc, | 
 | 12001 |                                        cast<CXXConstructorDecl>(MD)); | 
| Sean Hunt | 49634cf | 2011-05-13 06:10:58 +0000 | [diff] [blame] | 12002 |       break; | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12003 |     case CXXCopyConstructor: | 
 | 12004 |       DefineImplicitCopyConstructor(DefaultLoc, cast<CXXConstructorDecl>(MD)); | 
| Sean Hunt | e4246a6 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 12005 |       break; | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12006 |     case CXXCopyAssignment: | 
 | 12007 |       DefineImplicitCopyAssignment(DefaultLoc, MD); | 
| Sean Hunt | 2b18808 | 2011-05-14 05:23:28 +0000 | [diff] [blame] | 12008 |       break; | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12009 |     case CXXDestructor: | 
 | 12010 |       DefineImplicitDestructor(DefaultLoc, cast<CXXDestructorDecl>(MD)); | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 12011 |       break; | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12012 |     case CXXMoveConstructor: | 
 | 12013 |       DefineImplicitMoveConstructor(DefaultLoc, cast<CXXConstructorDecl>(MD)); | 
| Sean Hunt | 8271317 | 2011-05-25 23:16:36 +0000 | [diff] [blame] | 12014 |       break; | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12015 |     case CXXMoveAssignment: | 
 | 12016 |       DefineImplicitMoveAssignment(DefaultLoc, MD); | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 12017 |       break; | 
| Sebastian Redl | 85ea7aa | 2011-08-30 19:58:05 +0000 | [diff] [blame] | 12018 |     case CXXInvalid: | 
| David Blaikie | b219cfc | 2011-09-23 05:06:16 +0000 | [diff] [blame] | 12019 |       llvm_unreachable("Invalid special member."); | 
| Sean Hunt | e4246a6 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 12020 |     } | 
 | 12021 |   } else { | 
 | 12022 |     Diag(DefaultLoc, diag::err_default_special_members); | 
 | 12023 |   } | 
 | 12024 | } | 
 | 12025 |  | 
| Sebastian Redl | 13e8854 | 2009-04-27 21:33:24 +0000 | [diff] [blame] | 12026 | static void SearchForReturnInStmt(Sema &Self, Stmt *S) { | 
| John McCall | 7502c1d | 2011-02-13 04:07:26 +0000 | [diff] [blame] | 12027 |   for (Stmt::child_range CI = S->children(); CI; ++CI) { | 
| Sebastian Redl | 13e8854 | 2009-04-27 21:33:24 +0000 | [diff] [blame] | 12028 |     Stmt *SubStmt = *CI; | 
 | 12029 |     if (!SubStmt) | 
 | 12030 |       continue; | 
 | 12031 |     if (isa<ReturnStmt>(SubStmt)) | 
| Daniel Dunbar | 96a0014 | 2012-03-09 18:35:03 +0000 | [diff] [blame] | 12032 |       Self.Diag(SubStmt->getLocStart(), | 
| Sebastian Redl | 13e8854 | 2009-04-27 21:33:24 +0000 | [diff] [blame] | 12033 |            diag::err_return_in_constructor_handler); | 
 | 12034 |     if (!isa<Expr>(SubStmt)) | 
 | 12035 |       SearchForReturnInStmt(Self, SubStmt); | 
 | 12036 |   } | 
 | 12037 | } | 
 | 12038 |  | 
 | 12039 | void Sema::DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock) { | 
 | 12040 |   for (unsigned I = 0, E = TryBlock->getNumHandlers(); I != E; ++I) { | 
 | 12041 |     CXXCatchStmt *Handler = TryBlock->getHandler(I); | 
 | 12042 |     SearchForReturnInStmt(*this, Handler); | 
 | 12043 |   } | 
 | 12044 | } | 
| Anders Carlsson | d7ba27d | 2009-05-14 01:09:04 +0000 | [diff] [blame] | 12045 |  | 
| David Blaikie | 299adab | 2013-01-18 23:03:15 +0000 | [diff] [blame] | 12046 | bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New, | 
| Aaron Ballman | fff3248 | 2012-12-09 17:45:41 +0000 | [diff] [blame] | 12047 |                                              const CXXMethodDecl *Old) { | 
 | 12048 |   const FunctionType *NewFT = New->getType()->getAs<FunctionType>(); | 
 | 12049 |   const FunctionType *OldFT = Old->getType()->getAs<FunctionType>(); | 
 | 12050 |  | 
 | 12051 |   CallingConv NewCC = NewFT->getCallConv(), OldCC = OldFT->getCallConv(); | 
 | 12052 |  | 
 | 12053 |   // If the calling conventions match, everything is fine | 
 | 12054 |   if (NewCC == OldCC) | 
 | 12055 |     return false; | 
 | 12056 |  | 
| Reid Kleckner | ef07203 | 2013-08-27 23:08:25 +0000 | [diff] [blame] | 12057 |   Diag(New->getLocation(), | 
 | 12058 |        diag::err_conflicting_overriding_cc_attributes) | 
 | 12059 |     << New->getDeclName() << New->getType() << Old->getType(); | 
 | 12060 |   Diag(Old->getLocation(), diag::note_overridden_virtual_function); | 
 | 12061 |   return true; | 
| Aaron Ballman | fff3248 | 2012-12-09 17:45:41 +0000 | [diff] [blame] | 12062 | } | 
 | 12063 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12064 | bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New, | 
| Anders Carlsson | d7ba27d | 2009-05-14 01:09:04 +0000 | [diff] [blame] | 12065 |                                              const CXXMethodDecl *Old) { | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 12066 |   QualType NewTy = New->getType()->getAs<FunctionType>()->getResultType(); | 
 | 12067 |   QualType OldTy = Old->getType()->getAs<FunctionType>()->getResultType(); | 
| Anders Carlsson | d7ba27d | 2009-05-14 01:09:04 +0000 | [diff] [blame] | 12068 |  | 
| Chandler Carruth | 7385779 | 2010-02-15 11:53:20 +0000 | [diff] [blame] | 12069 |   if (Context.hasSameType(NewTy, OldTy) || | 
 | 12070 |       NewTy->isDependentType() || OldTy->isDependentType()) | 
| Anders Carlsson | d7ba27d | 2009-05-14 01:09:04 +0000 | [diff] [blame] | 12071 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12072 |  | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12073 |   // Check if the return types are covariant | 
 | 12074 |   QualType NewClassTy, OldClassTy; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12075 |  | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12076 |   /// Both types must be pointers or references to classes. | 
| Anders Carlsson | f2a04bf | 2010-01-22 17:37:20 +0000 | [diff] [blame] | 12077 |   if (const PointerType *NewPT = NewTy->getAs<PointerType>()) { | 
 | 12078 |     if (const PointerType *OldPT = OldTy->getAs<PointerType>()) { | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12079 |       NewClassTy = NewPT->getPointeeType(); | 
 | 12080 |       OldClassTy = OldPT->getPointeeType(); | 
 | 12081 |     } | 
| Anders Carlsson | f2a04bf | 2010-01-22 17:37:20 +0000 | [diff] [blame] | 12082 |   } else if (const ReferenceType *NewRT = NewTy->getAs<ReferenceType>()) { | 
 | 12083 |     if (const ReferenceType *OldRT = OldTy->getAs<ReferenceType>()) { | 
 | 12084 |       if (NewRT->getTypeClass() == OldRT->getTypeClass()) { | 
 | 12085 |         NewClassTy = NewRT->getPointeeType(); | 
 | 12086 |         OldClassTy = OldRT->getPointeeType(); | 
 | 12087 |       } | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12088 |     } | 
 | 12089 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12090 |  | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12091 |   // The return types aren't either both pointers or references to a class type. | 
 | 12092 |   if (NewClassTy.isNull()) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12093 |     Diag(New->getLocation(), | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12094 |          diag::err_different_return_type_for_overriding_virtual_function) | 
 | 12095 |       << New->getDeclName() << NewTy << OldTy; | 
 | 12096 |     Diag(Old->getLocation(), diag::note_overridden_virtual_function); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12097 |  | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12098 |     return true; | 
 | 12099 |   } | 
| Anders Carlsson | d7ba27d | 2009-05-14 01:09:04 +0000 | [diff] [blame] | 12100 |  | 
| Anders Carlsson | be2e205 | 2009-12-31 18:34:24 +0000 | [diff] [blame] | 12101 |   // C++ [class.virtual]p6: | 
 | 12102 |   //   If the return type of D::f differs from the return type of B::f, the  | 
 | 12103 |   //   class type in the return type of D::f shall be complete at the point of | 
 | 12104 |   //   declaration of D::f or shall be the class type D. | 
| Anders Carlsson | ac4c939 | 2009-12-31 18:54:35 +0000 | [diff] [blame] | 12105 |   if (const RecordType *RT = NewClassTy->getAs<RecordType>()) { | 
 | 12106 |     if (!RT->isBeingDefined() && | 
 | 12107 |         RequireCompleteType(New->getLocation(), NewClassTy,  | 
| Douglas Gregor | d10099e | 2012-05-04 16:32:21 +0000 | [diff] [blame] | 12108 |                             diag::err_covariant_return_incomplete, | 
 | 12109 |                             New->getDeclName())) | 
| Anders Carlsson | be2e205 | 2009-12-31 18:34:24 +0000 | [diff] [blame] | 12110 |     return true; | 
| Anders Carlsson | ac4c939 | 2009-12-31 18:54:35 +0000 | [diff] [blame] | 12111 |   } | 
| Anders Carlsson | be2e205 | 2009-12-31 18:34:24 +0000 | [diff] [blame] | 12112 |  | 
| Douglas Gregor | a4923eb | 2009-11-16 21:35:15 +0000 | [diff] [blame] | 12113 |   if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) { | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12114 |     // Check if the new class derives from the old class. | 
 | 12115 |     if (!IsDerivedFrom(NewClassTy, OldClassTy)) { | 
 | 12116 |       Diag(New->getLocation(), | 
 | 12117 |            diag::err_covariant_return_not_derived) | 
 | 12118 |       << New->getDeclName() << NewTy << OldTy; | 
 | 12119 |       Diag(Old->getLocation(), diag::note_overridden_virtual_function); | 
 | 12120 |       return true; | 
 | 12121 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12122 |  | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12123 |     // Check if we the conversion from derived to base is valid. | 
| John McCall | 58e6f34 | 2010-03-16 05:22:47 +0000 | [diff] [blame] | 12124 |     if (CheckDerivedToBaseConversion(NewClassTy, OldClassTy, | 
| Anders Carlsson | e25a96c | 2010-04-24 17:11:09 +0000 | [diff] [blame] | 12125 |                     diag::err_covariant_return_inaccessible_base, | 
 | 12126 |                     diag::err_covariant_return_ambiguous_derived_to_base_conv, | 
 | 12127 |                     // FIXME: Should this point to the return type? | 
 | 12128 |                     New->getLocation(), SourceRange(), New->getDeclName(), 0)) { | 
| John McCall | eee1d54 | 2011-02-14 07:13:47 +0000 | [diff] [blame] | 12129 |       // FIXME: this note won't trigger for delayed access control | 
 | 12130 |       // diagnostics, and it's impossible to get an undelayed error | 
 | 12131 |       // here from access control during the original parse because | 
 | 12132 |       // the ParsingDeclSpec/ParsingDeclarator are still in scope. | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12133 |       Diag(Old->getLocation(), diag::note_overridden_virtual_function); | 
 | 12134 |       return true; | 
 | 12135 |     } | 
 | 12136 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12137 |  | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12138 |   // The qualifiers of the return types must be the same. | 
| Anders Carlsson | f2a04bf | 2010-01-22 17:37:20 +0000 | [diff] [blame] | 12139 |   if (NewTy.getLocalCVRQualifiers() != OldTy.getLocalCVRQualifiers()) { | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12140 |     Diag(New->getLocation(), | 
 | 12141 |          diag::err_covariant_return_type_different_qualifications) | 
| Anders Carlsson | d7ba27d | 2009-05-14 01:09:04 +0000 | [diff] [blame] | 12142 |     << New->getDeclName() << NewTy << OldTy; | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12143 |     Diag(Old->getLocation(), diag::note_overridden_virtual_function); | 
 | 12144 |     return true; | 
 | 12145 |   }; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12146 |  | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12147 |  | 
 | 12148 |   // The new class type must have the same or less qualifiers as the old type. | 
 | 12149 |   if (NewClassTy.isMoreQualifiedThan(OldClassTy)) { | 
 | 12150 |     Diag(New->getLocation(), | 
 | 12151 |          diag::err_covariant_return_type_class_type_more_qualified) | 
 | 12152 |     << New->getDeclName() << NewTy << OldTy; | 
 | 12153 |     Diag(Old->getLocation(), diag::note_overridden_virtual_function); | 
 | 12154 |     return true; | 
 | 12155 |   }; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 12156 |  | 
| Anders Carlsson | c3a68b2 | 2009-05-14 19:52:19 +0000 | [diff] [blame] | 12157 |   return false; | 
| Anders Carlsson | d7ba27d | 2009-05-14 01:09:04 +0000 | [diff] [blame] | 12158 | } | 
| Argyrios Kyrtzidis | 0ffd9ff | 2009-06-17 22:50:06 +0000 | [diff] [blame] | 12159 |  | 
| Douglas Gregor | 4ba3136 | 2009-12-01 17:24:26 +0000 | [diff] [blame] | 12160 | /// \brief Mark the given method pure. | 
 | 12161 | /// | 
 | 12162 | /// \param Method the method to be marked pure. | 
 | 12163 | /// | 
 | 12164 | /// \param InitRange the source range that covers the "0" initializer. | 
 | 12165 | bool Sema::CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange) { | 
| Abramo Bagnara | 796aa44 | 2011-03-12 11:17:06 +0000 | [diff] [blame] | 12166 |   SourceLocation EndLoc = InitRange.getEnd(); | 
 | 12167 |   if (EndLoc.isValid()) | 
 | 12168 |     Method->setRangeEnd(EndLoc); | 
 | 12169 |  | 
| Douglas Gregor | 4ba3136 | 2009-12-01 17:24:26 +0000 | [diff] [blame] | 12170 |   if (Method->isVirtual() || Method->getParent()->isDependentContext()) { | 
 | 12171 |     Method->setPure(); | 
| Douglas Gregor | 4ba3136 | 2009-12-01 17:24:26 +0000 | [diff] [blame] | 12172 |     return false; | 
| Abramo Bagnara | 796aa44 | 2011-03-12 11:17:06 +0000 | [diff] [blame] | 12173 |   } | 
| Douglas Gregor | 4ba3136 | 2009-12-01 17:24:26 +0000 | [diff] [blame] | 12174 |  | 
 | 12175 |   if (!Method->isInvalidDecl()) | 
 | 12176 |     Diag(Method->getLocation(), diag::err_non_virtual_pure) | 
 | 12177 |       << Method->getDeclName() << InitRange; | 
 | 12178 |   return true; | 
 | 12179 | } | 
 | 12180 |  | 
| Douglas Gregor | 552e299 | 2012-02-21 02:22:07 +0000 | [diff] [blame] | 12181 | /// \brief Determine whether the given declaration is a static data member. | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12182 | static bool isStaticDataMember(const Decl *D) { | 
 | 12183 |   if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(D)) | 
 | 12184 |     return Var->isStaticDataMember(); | 
 | 12185 |  | 
 | 12186 |   return false; | 
| Douglas Gregor | 552e299 | 2012-02-21 02:22:07 +0000 | [diff] [blame] | 12187 | } | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12188 |  | 
| John McCall | 731ad84 | 2009-12-19 09:28:58 +0000 | [diff] [blame] | 12189 | /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse | 
 | 12190 | /// an initializer for the out-of-line declaration 'Dcl'.  The scope | 
 | 12191 | /// is a fresh scope pushed for just this purpose. | 
 | 12192 | /// | 
| Argyrios Kyrtzidis | 0ffd9ff | 2009-06-17 22:50:06 +0000 | [diff] [blame] | 12193 | /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a | 
 | 12194 | /// static data member of class X, names should be looked up in the scope of | 
 | 12195 | /// class X. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 12196 | void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) { | 
| Argyrios Kyrtzidis | 0ffd9ff | 2009-06-17 22:50:06 +0000 | [diff] [blame] | 12197 |   // If there is no declaration, there was an error parsing it. | 
| Argyrios Kyrtzidis | b65abda | 2011-04-22 18:52:25 +0000 | [diff] [blame] | 12198 |   if (D == 0 || D->isInvalidDecl()) return; | 
| Argyrios Kyrtzidis | 0ffd9ff | 2009-06-17 22:50:06 +0000 | [diff] [blame] | 12199 |  | 
| John McCall | 731ad84 | 2009-12-19 09:28:58 +0000 | [diff] [blame] | 12200 |   // We should only get called for declarations with scope specifiers, like: | 
 | 12201 |   //   int foo::bar; | 
 | 12202 |   assert(D->isOutOfLine()); | 
| John McCall | 7a1dc56 | 2009-12-19 10:49:29 +0000 | [diff] [blame] | 12203 |   EnterDeclaratorContext(S, D->getDeclContext()); | 
| Douglas Gregor | 552e299 | 2012-02-21 02:22:07 +0000 | [diff] [blame] | 12204 |    | 
 | 12205 |   // If we are parsing the initializer for a static data member, push a | 
 | 12206 |   // new expression evaluation context that is associated with this static | 
 | 12207 |   // data member. | 
 | 12208 |   if (isStaticDataMember(D)) | 
 | 12209 |     PushExpressionEvaluationContext(PotentiallyEvaluated, D); | 
| Argyrios Kyrtzidis | 0ffd9ff | 2009-06-17 22:50:06 +0000 | [diff] [blame] | 12210 | } | 
 | 12211 |  | 
 | 12212 | /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 12213 | /// initializer for the out-of-line declaration 'D'. | 
 | 12214 | void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) { | 
| Argyrios Kyrtzidis | 0ffd9ff | 2009-06-17 22:50:06 +0000 | [diff] [blame] | 12215 |   // If there is no declaration, there was an error parsing it. | 
| Argyrios Kyrtzidis | b65abda | 2011-04-22 18:52:25 +0000 | [diff] [blame] | 12216 |   if (D == 0 || D->isInvalidDecl()) return; | 
| Argyrios Kyrtzidis | 0ffd9ff | 2009-06-17 22:50:06 +0000 | [diff] [blame] | 12217 |  | 
| Douglas Gregor | 552e299 | 2012-02-21 02:22:07 +0000 | [diff] [blame] | 12218 |   if (isStaticDataMember(D)) | 
 | 12219 |     PopExpressionEvaluationContext();   | 
 | 12220 |  | 
| John McCall | 731ad84 | 2009-12-19 09:28:58 +0000 | [diff] [blame] | 12221 |   assert(D->isOutOfLine()); | 
| John McCall | 7a1dc56 | 2009-12-19 10:49:29 +0000 | [diff] [blame] | 12222 |   ExitDeclaratorContext(S); | 
| Argyrios Kyrtzidis | 0ffd9ff | 2009-06-17 22:50:06 +0000 | [diff] [blame] | 12223 | } | 
| Douglas Gregor | 99e9b4d | 2009-11-25 00:27:52 +0000 | [diff] [blame] | 12224 |  | 
 | 12225 | /// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a | 
 | 12226 | /// C++ if/switch/while/for statement. | 
 | 12227 | /// e.g: "if (int x = f()) {...}" | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 12228 | DeclResult Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) { | 
| Douglas Gregor | 99e9b4d | 2009-11-25 00:27:52 +0000 | [diff] [blame] | 12229 |   // C++ 6.4p2: | 
 | 12230 |   // The declarator shall not specify a function or an array. | 
 | 12231 |   // The type-specifier-seq shall not contain typedef and shall not declare a | 
 | 12232 |   // new class or enumeration. | 
 | 12233 |   assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && | 
 | 12234 |          "Parser allowed 'typedef' as storage class of condition decl."); | 
| Argyrios Kyrtzidis | db7abf7 | 2011-06-28 03:01:12 +0000 | [diff] [blame] | 12235 |  | 
 | 12236 |   Decl *Dcl = ActOnDeclarator(S, D); | 
| Douglas Gregor | 9a30c99 | 2011-07-05 16:13:20 +0000 | [diff] [blame] | 12237 |   if (!Dcl) | 
 | 12238 |     return true; | 
 | 12239 |  | 
| Argyrios Kyrtzidis | db7abf7 | 2011-06-28 03:01:12 +0000 | [diff] [blame] | 12240 |   if (isa<FunctionDecl>(Dcl)) { // The declarator shall not specify a function. | 
 | 12241 |     Diag(Dcl->getLocation(), diag::err_invalid_use_of_function_type) | 
| Douglas Gregor | 99e9b4d | 2009-11-25 00:27:52 +0000 | [diff] [blame] | 12242 |       << D.getSourceRange(); | 
| Douglas Gregor | 9a30c99 | 2011-07-05 16:13:20 +0000 | [diff] [blame] | 12243 |     return true; | 
| Douglas Gregor | 99e9b4d | 2009-11-25 00:27:52 +0000 | [diff] [blame] | 12244 |   } | 
| Douglas Gregor | 99e9b4d | 2009-11-25 00:27:52 +0000 | [diff] [blame] | 12245 |  | 
| Douglas Gregor | 99e9b4d | 2009-11-25 00:27:52 +0000 | [diff] [blame] | 12246 |   return Dcl; | 
 | 12247 | } | 
| Anders Carlsson | 5ec02ae | 2009-12-02 17:15:43 +0000 | [diff] [blame] | 12248 |  | 
| Douglas Gregor | dfe6543 | 2011-07-28 19:11:31 +0000 | [diff] [blame] | 12249 | void Sema::LoadExternalVTableUses() { | 
 | 12250 |   if (!ExternalSource) | 
 | 12251 |     return; | 
 | 12252 |    | 
 | 12253 |   SmallVector<ExternalVTableUse, 4> VTables; | 
 | 12254 |   ExternalSource->ReadUsedVTables(VTables); | 
 | 12255 |   SmallVector<VTableUse, 4> NewUses; | 
 | 12256 |   for (unsigned I = 0, N = VTables.size(); I != N; ++I) { | 
 | 12257 |     llvm::DenseMap<CXXRecordDecl *, bool>::iterator Pos | 
 | 12258 |       = VTablesUsed.find(VTables[I].Record); | 
 | 12259 |     // Even if a definition wasn't required before, it may be required now. | 
 | 12260 |     if (Pos != VTablesUsed.end()) { | 
 | 12261 |       if (!Pos->second && VTables[I].DefinitionRequired) | 
 | 12262 |         Pos->second = true; | 
 | 12263 |       continue; | 
 | 12264 |     } | 
 | 12265 |      | 
 | 12266 |     VTablesUsed[VTables[I].Record] = VTables[I].DefinitionRequired; | 
 | 12267 |     NewUses.push_back(VTableUse(VTables[I].Record, VTables[I].Location)); | 
 | 12268 |   } | 
 | 12269 |    | 
 | 12270 |   VTableUses.insert(VTableUses.begin(), NewUses.begin(), NewUses.end()); | 
 | 12271 | } | 
 | 12272 |  | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12273 | void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, | 
 | 12274 |                           bool DefinitionRequired) { | 
 | 12275 |   // Ignore any vtable uses in unevaluated operands or for classes that do | 
 | 12276 |   // not have a vtable. | 
 | 12277 |   if (!Class->isDynamicClass() || Class->isDependentContext() || | 
| John McCall | aeeacf7 | 2013-05-03 00:10:13 +0000 | [diff] [blame] | 12278 |       CurContext->isDependentContext() || isUnevaluatedContext()) | 
| Rafael Espindola | bbf58bb | 2010-03-10 02:19:29 +0000 | [diff] [blame] | 12279 |     return; | 
 | 12280 |  | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12281 |   // Try to insert this class into the map. | 
| Douglas Gregor | dfe6543 | 2011-07-28 19:11:31 +0000 | [diff] [blame] | 12282 |   LoadExternalVTableUses(); | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12283 |   Class = cast<CXXRecordDecl>(Class->getCanonicalDecl()); | 
 | 12284 |   std::pair<llvm::DenseMap<CXXRecordDecl *, bool>::iterator, bool> | 
 | 12285 |     Pos = VTablesUsed.insert(std::make_pair(Class, DefinitionRequired)); | 
 | 12286 |   if (!Pos.second) { | 
| Daniel Dunbar | b9aefa7 | 2010-05-25 00:33:13 +0000 | [diff] [blame] | 12287 |     // If we already had an entry, check to see if we are promoting this vtable | 
 | 12288 |     // to required a definition. If so, we need to reappend to the VTableUses | 
 | 12289 |     // list, since we may have already processed the first entry. | 
 | 12290 |     if (DefinitionRequired && !Pos.first->second) { | 
 | 12291 |       Pos.first->second = true; | 
 | 12292 |     } else { | 
 | 12293 |       // Otherwise, we can early exit. | 
 | 12294 |       return; | 
 | 12295 |     } | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12296 |   } | 
 | 12297 |  | 
 | 12298 |   // Local classes need to have their virtual members marked | 
 | 12299 |   // immediately. For all other classes, we mark their virtual members | 
 | 12300 |   // at the end of the translation unit. | 
 | 12301 |   if (Class->isLocalClass()) | 
 | 12302 |     MarkVirtualMembersReferenced(Loc, Class); | 
| Daniel Dunbar | 380c213 | 2010-05-11 21:32:35 +0000 | [diff] [blame] | 12303 |   else | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12304 |     VTableUses.push_back(std::make_pair(Class, Loc)); | 
| Douglas Gregor | bbbe074 | 2010-05-11 20:24:17 +0000 | [diff] [blame] | 12305 | } | 
 | 12306 |  | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12307 | bool Sema::DefineUsedVTables() { | 
| Douglas Gregor | dfe6543 | 2011-07-28 19:11:31 +0000 | [diff] [blame] | 12308 |   LoadExternalVTableUses(); | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12309 |   if (VTableUses.empty()) | 
| Anders Carlsson | d6a637f | 2009-12-07 08:24:59 +0000 | [diff] [blame] | 12310 |     return false; | 
| Chandler Carruth | aee543a | 2010-12-12 21:36:11 +0000 | [diff] [blame] | 12311 |  | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12312 |   // Note: The VTableUses vector could grow as a result of marking | 
 | 12313 |   // the members of a class as "used", so we check the size each | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 12314 |   // time through the loop and prefer indices (which are stable) to | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12315 |   // iterators (which are not). | 
| Douglas Gregor | 7884403 | 2011-04-22 22:25:37 +0000 | [diff] [blame] | 12316 |   bool DefinedAnything = false; | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12317 |   for (unsigned I = 0; I != VTableUses.size(); ++I) { | 
| Daniel Dunbar | e669f89 | 2010-05-25 00:32:58 +0000 | [diff] [blame] | 12318 |     CXXRecordDecl *Class = VTableUses[I].first->getDefinition(); | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12319 |     if (!Class) | 
 | 12320 |       continue; | 
 | 12321 |  | 
 | 12322 |     SourceLocation Loc = VTableUses[I].second; | 
 | 12323 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 12324 |     bool DefineVTable = true; | 
 | 12325 |  | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12326 |     // If this class has a key function, but that key function is | 
 | 12327 |     // defined in another translation unit, we don't need to emit the | 
 | 12328 |     // vtable even though we're using it. | 
| John McCall | d5617ee | 2013-01-25 22:31:03 +0000 | [diff] [blame] | 12329 |     const CXXMethodDecl *KeyFunction = Context.getCurrentKeyFunction(Class); | 
| Argyrios Kyrtzidis | 06a54a3 | 2010-07-07 11:31:19 +0000 | [diff] [blame] | 12330 |     if (KeyFunction && !KeyFunction->hasBody()) { | 
| Rafael Espindola | fc21813 | 2013-08-26 23:23:21 +0000 | [diff] [blame] | 12331 |       // The key function is in another translation unit. | 
 | 12332 |       DefineVTable = false; | 
 | 12333 |       TemplateSpecializationKind TSK = | 
 | 12334 |           KeyFunction->getTemplateSpecializationKind(); | 
 | 12335 |       assert(TSK != TSK_ExplicitInstantiationDefinition && | 
 | 12336 |              TSK != TSK_ImplicitInstantiation && | 
 | 12337 |              "Instantiations don't have key functions"); | 
 | 12338 |       (void)TSK; | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12339 |     } else if (!KeyFunction) { | 
 | 12340 |       // If we have a class with no key function that is the subject | 
 | 12341 |       // of an explicit instantiation declaration, suppress the | 
 | 12342 |       // vtable; it will live with the explicit instantiation | 
 | 12343 |       // definition. | 
 | 12344 |       bool IsExplicitInstantiationDeclaration | 
 | 12345 |         = Class->getTemplateSpecializationKind() | 
 | 12346 |                                       == TSK_ExplicitInstantiationDeclaration; | 
 | 12347 |       for (TagDecl::redecl_iterator R = Class->redecls_begin(), | 
 | 12348 |                                  REnd = Class->redecls_end(); | 
 | 12349 |            R != REnd; ++R) { | 
 | 12350 |         TemplateSpecializationKind TSK | 
 | 12351 |           = cast<CXXRecordDecl>(*R)->getTemplateSpecializationKind(); | 
 | 12352 |         if (TSK == TSK_ExplicitInstantiationDeclaration) | 
 | 12353 |           IsExplicitInstantiationDeclaration = true; | 
 | 12354 |         else if (TSK == TSK_ExplicitInstantiationDefinition) { | 
 | 12355 |           IsExplicitInstantiationDeclaration = false; | 
 | 12356 |           break; | 
 | 12357 |         } | 
 | 12358 |       } | 
 | 12359 |  | 
 | 12360 |       if (IsExplicitInstantiationDeclaration) | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 12361 |         DefineVTable = false; | 
 | 12362 |     } | 
 | 12363 |  | 
 | 12364 |     // The exception specifications for all virtual members may be needed even | 
 | 12365 |     // if we are not providing an authoritative form of the vtable in this TU. | 
 | 12366 |     // We may choose to emit it available_externally anyway. | 
 | 12367 |     if (!DefineVTable) { | 
 | 12368 |       MarkVirtualMemberExceptionSpecsNeeded(Loc, Class); | 
 | 12369 |       continue; | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12370 |     } | 
 | 12371 |  | 
 | 12372 |     // Mark all of the virtual members of this class as referenced, so | 
 | 12373 |     // that we can build a vtable. Then, tell the AST consumer that a | 
 | 12374 |     // vtable for this class is required. | 
| Douglas Gregor | 7884403 | 2011-04-22 22:25:37 +0000 | [diff] [blame] | 12375 |     DefinedAnything = true; | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12376 |     MarkVirtualMembersReferenced(Loc, Class); | 
 | 12377 |     CXXRecordDecl *Canonical = cast<CXXRecordDecl>(Class->getCanonicalDecl()); | 
 | 12378 |     Consumer.HandleVTable(Class, VTablesUsed[Canonical]); | 
 | 12379 |  | 
 | 12380 |     // Optionally warn if we're emitting a weak vtable. | 
| Rafael Espindola | 181e3ec | 2013-05-13 00:12:11 +0000 | [diff] [blame] | 12381 |     if (Class->isExternallyVisible() && | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12382 |         Class->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) { | 
| Douglas Gregor | a120d01 | 2011-09-23 19:04:03 +0000 | [diff] [blame] | 12383 |       const FunctionDecl *KeyFunctionDef = 0; | 
 | 12384 |       if (!KeyFunction ||  | 
 | 12385 |           (KeyFunction->hasBody(KeyFunctionDef) &&  | 
 | 12386 |            KeyFunctionDef->isInlined())) | 
| David Blaikie | 44d95b5 | 2011-12-09 18:32:50 +0000 | [diff] [blame] | 12387 |         Diag(Class->getLocation(), Class->getTemplateSpecializationKind() == | 
 | 12388 |              TSK_ExplicitInstantiationDefinition  | 
 | 12389 |              ? diag::warn_weak_template_vtable : diag::warn_weak_vtable)  | 
 | 12390 |           << Class; | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12391 |     } | 
| Anders Carlsson | 5ec02ae | 2009-12-02 17:15:43 +0000 | [diff] [blame] | 12392 |   } | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 12393 |   VTableUses.clear(); | 
 | 12394 |  | 
| Douglas Gregor | 7884403 | 2011-04-22 22:25:37 +0000 | [diff] [blame] | 12395 |   return DefinedAnything; | 
| Anders Carlsson | 5ec02ae | 2009-12-02 17:15:43 +0000 | [diff] [blame] | 12396 | } | 
| Anders Carlsson | d6a637f | 2009-12-07 08:24:59 +0000 | [diff] [blame] | 12397 |  | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 12398 | void Sema::MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc, | 
 | 12399 |                                                  const CXXRecordDecl *RD) { | 
 | 12400 |   for (CXXRecordDecl::method_iterator I = RD->method_begin(), | 
 | 12401 |                                       E = RD->method_end(); I != E; ++I) | 
 | 12402 |     if ((*I)->isVirtual() && !(*I)->isPure()) | 
 | 12403 |       ResolveExceptionSpec(Loc, (*I)->getType()->castAs<FunctionProtoType>()); | 
 | 12404 | } | 
 | 12405 |  | 
| Rafael Espindola | 3e1ae93 | 2010-03-26 00:36:59 +0000 | [diff] [blame] | 12406 | void Sema::MarkVirtualMembersReferenced(SourceLocation Loc, | 
 | 12407 |                                         const CXXRecordDecl *RD) { | 
| Richard Smith | ff817f7 | 2012-07-07 06:59:51 +0000 | [diff] [blame] | 12408 |   // Mark all functions which will appear in RD's vtable as used. | 
 | 12409 |   CXXFinalOverriderMap FinalOverriders; | 
 | 12410 |   RD->getFinalOverriders(FinalOverriders); | 
 | 12411 |   for (CXXFinalOverriderMap::const_iterator I = FinalOverriders.begin(), | 
 | 12412 |                                             E = FinalOverriders.end(); | 
 | 12413 |        I != E; ++I) { | 
 | 12414 |     for (OverridingMethods::const_iterator OI = I->second.begin(), | 
 | 12415 |                                            OE = I->second.end(); | 
 | 12416 |          OI != OE; ++OI) { | 
 | 12417 |       assert(OI->second.size() > 0 && "no final overrider"); | 
 | 12418 |       CXXMethodDecl *Overrider = OI->second.front().Method; | 
| Anders Carlsson | d6a637f | 2009-12-07 08:24:59 +0000 | [diff] [blame] | 12419 |  | 
| Richard Smith | ff817f7 | 2012-07-07 06:59:51 +0000 | [diff] [blame] | 12420 |       // C++ [basic.def.odr]p2: | 
 | 12421 |       //   [...] A virtual member function is used if it is not pure. [...] | 
 | 12422 |       if (!Overrider->isPure()) | 
 | 12423 |         MarkFunctionReferenced(Loc, Overrider); | 
 | 12424 |     } | 
| Anders Carlsson | d6a637f | 2009-12-07 08:24:59 +0000 | [diff] [blame] | 12425 |   } | 
| Rafael Espindola | 3e1ae93 | 2010-03-26 00:36:59 +0000 | [diff] [blame] | 12426 |  | 
 | 12427 |   // Only classes that have virtual bases need a VTT. | 
 | 12428 |   if (RD->getNumVBases() == 0) | 
 | 12429 |     return; | 
 | 12430 |  | 
 | 12431 |   for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), | 
 | 12432 |            e = RD->bases_end(); i != e; ++i) { | 
 | 12433 |     const CXXRecordDecl *Base = | 
 | 12434 |         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); | 
| Rafael Espindola | 3e1ae93 | 2010-03-26 00:36:59 +0000 | [diff] [blame] | 12435 |     if (Base->getNumVBases() == 0) | 
 | 12436 |       continue; | 
 | 12437 |     MarkVirtualMembersReferenced(Loc, Base); | 
 | 12438 |   } | 
| Anders Carlsson | d6a637f | 2009-12-07 08:24:59 +0000 | [diff] [blame] | 12439 | } | 
| Fariborz Jahanian | e4498c6 | 2010-04-28 16:11:27 +0000 | [diff] [blame] | 12440 |  | 
 | 12441 | /// SetIvarInitializers - This routine builds initialization ASTs for the | 
 | 12442 | /// Objective-C implementation whose ivars need be initialized. | 
 | 12443 | void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { | 
| David Blaikie | 4e4d084 | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 12444 |   if (!getLangOpts().CPlusPlus) | 
| Fariborz Jahanian | e4498c6 | 2010-04-28 16:11:27 +0000 | [diff] [blame] | 12445 |     return; | 
| Fariborz Jahanian | 2c18bb7 | 2010-08-20 21:21:08 +0000 | [diff] [blame] | 12446 |   if (ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) { | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 12447 |     SmallVector<ObjCIvarDecl*, 8> ivars; | 
| Fariborz Jahanian | e4498c6 | 2010-04-28 16:11:27 +0000 | [diff] [blame] | 12448 |     CollectIvarsToConstructOrDestruct(OID, ivars); | 
 | 12449 |     if (ivars.empty()) | 
 | 12450 |       return; | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 12451 |     SmallVector<CXXCtorInitializer*, 32> AllToInit; | 
| Fariborz Jahanian | e4498c6 | 2010-04-28 16:11:27 +0000 | [diff] [blame] | 12452 |     for (unsigned i = 0; i < ivars.size(); i++) { | 
 | 12453 |       FieldDecl *Field = ivars[i]; | 
| Douglas Gregor | 68dd3ee | 2010-05-20 02:24:22 +0000 | [diff] [blame] | 12454 |       if (Field->isInvalidDecl()) | 
 | 12455 |         continue; | 
 | 12456 |        | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 12457 |       CXXCtorInitializer *Member; | 
| Fariborz Jahanian | e4498c6 | 2010-04-28 16:11:27 +0000 | [diff] [blame] | 12458 |       InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field); | 
 | 12459 |       InitializationKind InitKind =  | 
 | 12460 |         InitializationKind::CreateDefault(ObjCImplementation->getLocation()); | 
| Dmitri Gribenko | 62ed889 | 2013-05-05 20:40:26 +0000 | [diff] [blame] | 12461 |  | 
 | 12462 |       InitializationSequence InitSeq(*this, InitEntity, InitKind, None); | 
 | 12463 |       ExprResult MemberInit = | 
 | 12464 |         InitSeq.Perform(*this, InitEntity, InitKind, None); | 
| Douglas Gregor | 53c374f | 2010-12-07 00:41:46 +0000 | [diff] [blame] | 12465 |       MemberInit = MaybeCreateExprWithCleanups(MemberInit); | 
| Fariborz Jahanian | e4498c6 | 2010-04-28 16:11:27 +0000 | [diff] [blame] | 12466 |       // Note, MemberInit could actually come back empty if no initialization  | 
 | 12467 |       // is required (e.g., because it would call a trivial default constructor) | 
 | 12468 |       if (!MemberInit.get() || MemberInit.isInvalid()) | 
 | 12469 |         continue; | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 12470 |  | 
| Fariborz Jahanian | e4498c6 | 2010-04-28 16:11:27 +0000 | [diff] [blame] | 12471 |       Member = | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 12472 |         new (Context) CXXCtorInitializer(Context, Field, SourceLocation(), | 
 | 12473 |                                          SourceLocation(), | 
 | 12474 |                                          MemberInit.takeAs<Expr>(), | 
 | 12475 |                                          SourceLocation()); | 
| Fariborz Jahanian | e4498c6 | 2010-04-28 16:11:27 +0000 | [diff] [blame] | 12476 |       AllToInit.push_back(Member); | 
| Douglas Gregor | 68dd3ee | 2010-05-20 02:24:22 +0000 | [diff] [blame] | 12477 |        | 
 | 12478 |       // Be sure that the destructor is accessible and is marked as referenced. | 
 | 12479 |       if (const RecordType *RecordTy | 
 | 12480 |                   = Context.getBaseElementType(Field->getType()) | 
 | 12481 |                                                         ->getAs<RecordType>()) { | 
 | 12482 |                     CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); | 
| Douglas Gregor | db89f28 | 2010-07-01 22:47:18 +0000 | [diff] [blame] | 12483 |         if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) { | 
| Eli Friedman | 5f2987c | 2012-02-02 03:46:19 +0000 | [diff] [blame] | 12484 |           MarkFunctionReferenced(Field->getLocation(), Destructor); | 
| Douglas Gregor | 68dd3ee | 2010-05-20 02:24:22 +0000 | [diff] [blame] | 12485 |           CheckDestructorAccess(Field->getLocation(), Destructor, | 
 | 12486 |                             PDiag(diag::err_access_dtor_ivar) | 
 | 12487 |                               << Context.getBaseElementType(Field->getType())); | 
 | 12488 |         } | 
 | 12489 |       }       | 
| Fariborz Jahanian | e4498c6 | 2010-04-28 16:11:27 +0000 | [diff] [blame] | 12490 |     } | 
 | 12491 |     ObjCImplementation->setIvarInitializers(Context,  | 
 | 12492 |                                             AllToInit.data(), AllToInit.size()); | 
 | 12493 |   } | 
 | 12494 | } | 
| Sean Hunt | fe57eef | 2011-05-04 05:57:24 +0000 | [diff] [blame] | 12495 |  | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12496 | static | 
 | 12497 | void DelegatingCycleHelper(CXXConstructorDecl* Ctor, | 
 | 12498 |                            llvm::SmallSet<CXXConstructorDecl*, 4> &Valid, | 
 | 12499 |                            llvm::SmallSet<CXXConstructorDecl*, 4> &Invalid, | 
 | 12500 |                            llvm::SmallSet<CXXConstructorDecl*, 4> &Current, | 
 | 12501 |                            Sema &S) { | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12502 |   if (Ctor->isInvalidDecl()) | 
 | 12503 |     return; | 
 | 12504 |  | 
| Richard Smith | a8eaf00 | 2012-08-23 06:16:52 +0000 | [diff] [blame] | 12505 |   CXXConstructorDecl *Target = Ctor->getTargetConstructor(); | 
 | 12506 |  | 
 | 12507 |   // Target may not be determinable yet, for instance if this is a dependent | 
 | 12508 |   // call in an uninstantiated template. | 
 | 12509 |   if (Target) { | 
 | 12510 |     const FunctionDecl *FNTarget = 0; | 
 | 12511 |     (void)Target->hasBody(FNTarget); | 
 | 12512 |     Target = const_cast<CXXConstructorDecl*>( | 
 | 12513 |       cast_or_null<CXXConstructorDecl>(FNTarget)); | 
 | 12514 |   } | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12515 |  | 
 | 12516 |   CXXConstructorDecl *Canonical = Ctor->getCanonicalDecl(), | 
 | 12517 |                      // Avoid dereferencing a null pointer here. | 
 | 12518 |                      *TCanonical = Target ? Target->getCanonicalDecl() : 0; | 
 | 12519 |  | 
 | 12520 |   if (!Current.insert(Canonical)) | 
 | 12521 |     return; | 
 | 12522 |  | 
 | 12523 |   // We know that beyond here, we aren't chaining into a cycle. | 
 | 12524 |   if (!Target || !Target->isDelegatingConstructor() || | 
 | 12525 |       Target->isInvalidDecl() || Valid.count(TCanonical)) { | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12526 |     Valid.insert(Current.begin(), Current.end()); | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12527 |     Current.clear(); | 
 | 12528 |   // We've hit a cycle. | 
 | 12529 |   } else if (TCanonical == Canonical || Invalid.count(TCanonical) || | 
 | 12530 |              Current.count(TCanonical)) { | 
 | 12531 |     // If we haven't diagnosed this cycle yet, do so now. | 
 | 12532 |     if (!Invalid.count(TCanonical)) { | 
 | 12533 |       S.Diag((*Ctor->init_begin())->getSourceLocation(), | 
| Sean Hunt | c159870 | 2011-05-05 00:05:47 +0000 | [diff] [blame] | 12534 |              diag::warn_delegating_ctor_cycle) | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12535 |         << Ctor; | 
 | 12536 |  | 
| Richard Smith | a8eaf00 | 2012-08-23 06:16:52 +0000 | [diff] [blame] | 12537 |       // Don't add a note for a function delegating directly to itself. | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12538 |       if (TCanonical != Canonical) | 
 | 12539 |         S.Diag(Target->getLocation(), diag::note_it_delegates_to); | 
 | 12540 |  | 
 | 12541 |       CXXConstructorDecl *C = Target; | 
 | 12542 |       while (C->getCanonicalDecl() != Canonical) { | 
| Richard Smith | a8eaf00 | 2012-08-23 06:16:52 +0000 | [diff] [blame] | 12543 |         const FunctionDecl *FNTarget = 0; | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12544 |         (void)C->getTargetConstructor()->hasBody(FNTarget); | 
 | 12545 |         assert(FNTarget && "Ctor cycle through bodiless function"); | 
 | 12546 |  | 
| Richard Smith | a8eaf00 | 2012-08-23 06:16:52 +0000 | [diff] [blame] | 12547 |         C = const_cast<CXXConstructorDecl*>( | 
 | 12548 |           cast<CXXConstructorDecl>(FNTarget)); | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12549 |         S.Diag(C->getLocation(), diag::note_which_delegates_to); | 
 | 12550 |       } | 
 | 12551 |     } | 
 | 12552 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12553 |     Invalid.insert(Current.begin(), Current.end()); | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12554 |     Current.clear(); | 
 | 12555 |   } else { | 
 | 12556 |     DelegatingCycleHelper(Target, Valid, Invalid, Current, S); | 
 | 12557 |   } | 
 | 12558 | } | 
 | 12559 |     | 
 | 12560 |  | 
| Sean Hunt | fe57eef | 2011-05-04 05:57:24 +0000 | [diff] [blame] | 12561 | void Sema::CheckDelegatingCtorCycles() { | 
 | 12562 |   llvm::SmallSet<CXXConstructorDecl*, 4> Valid, Invalid, Current; | 
 | 12563 |  | 
| Douglas Gregor | 0129b56 | 2011-07-27 21:57:17 +0000 | [diff] [blame] | 12564 |   for (DelegatingCtorDeclsType::iterator | 
 | 12565 |          I = DelegatingCtorDecls.begin(ExternalSource), | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12566 |          E = DelegatingCtorDecls.end(); | 
| Richard Smith | a8eaf00 | 2012-08-23 06:16:52 +0000 | [diff] [blame] | 12567 |        I != E; ++I) | 
 | 12568 |     DelegatingCycleHelper(*I, Valid, Invalid, Current, *this); | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12569 |  | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12570 |   for (llvm::SmallSet<CXXConstructorDecl *, 4>::iterator CI = Invalid.begin(), | 
 | 12571 |                                                          CE = Invalid.end(); | 
 | 12572 |        CI != CE; ++CI) | 
| Sean Hunt | ebcbe1d | 2011-05-04 23:29:54 +0000 | [diff] [blame] | 12573 |     (*CI)->setInvalidDecl(); | 
| Sean Hunt | fe57eef | 2011-05-04 05:57:24 +0000 | [diff] [blame] | 12574 | } | 
| Peter Collingbourne | 78dd67e | 2011-10-02 23:49:40 +0000 | [diff] [blame] | 12575 |  | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12576 | namespace { | 
 | 12577 |   /// \brief AST visitor that finds references to the 'this' expression. | 
 | 12578 |   class FindCXXThisExpr : public RecursiveASTVisitor<FindCXXThisExpr> { | 
 | 12579 |     Sema &S; | 
 | 12580 |      | 
 | 12581 |   public: | 
 | 12582 |     explicit FindCXXThisExpr(Sema &S) : S(S) { } | 
 | 12583 |      | 
 | 12584 |     bool VisitCXXThisExpr(CXXThisExpr *E) { | 
 | 12585 |       S.Diag(E->getLocation(), diag::err_this_static_member_func) | 
 | 12586 |         << E->isImplicit(); | 
 | 12587 |       return false; | 
 | 12588 |     } | 
 | 12589 |   }; | 
 | 12590 | } | 
 | 12591 |  | 
 | 12592 | bool Sema::checkThisInStaticMemberFunctionType(CXXMethodDecl *Method) { | 
 | 12593 |   TypeSourceInfo *TSInfo = Method->getTypeSourceInfo(); | 
 | 12594 |   if (!TSInfo) | 
 | 12595 |     return false; | 
 | 12596 |    | 
 | 12597 |   TypeLoc TL = TSInfo->getTypeLoc(); | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 12598 |   FunctionProtoTypeLoc ProtoTL = TL.getAs<FunctionProtoTypeLoc>(); | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12599 |   if (!ProtoTL) | 
 | 12600 |     return false; | 
 | 12601 |    | 
 | 12602 |   // C++11 [expr.prim.general]p3: | 
 | 12603 |   //   [The expression this] shall not appear before the optional  | 
 | 12604 |   //   cv-qualifier-seq and it shall not appear within the declaration of a  | 
 | 12605 |   //   static member function (although its type and value category are defined | 
 | 12606 |   //   within a static member function as they are within a non-static member | 
 | 12607 |   //   function). [ Note: this is because declaration matching does not occur | 
| NAKAMURA Takumi | c86d1fd | 2012-04-21 09:40:04 +0000 | [diff] [blame] | 12608 |   //  until the complete declarator is known. - end note ] | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 12609 |   const FunctionProtoType *Proto = ProtoTL.getTypePtr(); | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12610 |   FindCXXThisExpr Finder(*this); | 
 | 12611 |    | 
 | 12612 |   // If the return type came after the cv-qualifier-seq, check it now. | 
 | 12613 |   if (Proto->hasTrailingReturn() && | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 12614 |       !Finder.TraverseTypeLoc(ProtoTL.getResultLoc())) | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12615 |     return true; | 
 | 12616 |  | 
 | 12617 |   // Check the exception specification. | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12618 |   if (checkThisInStaticMemberFunctionExceptionSpec(Method)) | 
 | 12619 |     return true; | 
 | 12620 |    | 
 | 12621 |   return checkThisInStaticMemberFunctionAttributes(Method); | 
 | 12622 | } | 
 | 12623 |  | 
 | 12624 | bool Sema::checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method) { | 
 | 12625 |   TypeSourceInfo *TSInfo = Method->getTypeSourceInfo(); | 
 | 12626 |   if (!TSInfo) | 
 | 12627 |     return false; | 
 | 12628 |    | 
 | 12629 |   TypeLoc TL = TSInfo->getTypeLoc(); | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 12630 |   FunctionProtoTypeLoc ProtoTL = TL.getAs<FunctionProtoTypeLoc>(); | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12631 |   if (!ProtoTL) | 
 | 12632 |     return false; | 
 | 12633 |    | 
| David Blaikie | 39e6ab4 | 2013-02-18 22:06:02 +0000 | [diff] [blame] | 12634 |   const FunctionProtoType *Proto = ProtoTL.getTypePtr(); | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12635 |   FindCXXThisExpr Finder(*this); | 
 | 12636 |  | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12637 |   switch (Proto->getExceptionSpecType()) { | 
| Richard Smith | e6975e9 | 2012-04-17 00:58:00 +0000 | [diff] [blame] | 12638 |   case EST_Uninstantiated: | 
| Richard Smith | b9d0b76 | 2012-07-27 04:22:15 +0000 | [diff] [blame] | 12639 |   case EST_Unevaluated: | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12640 |   case EST_BasicNoexcept: | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12641 |   case EST_DynamicNone: | 
 | 12642 |   case EST_MSAny: | 
 | 12643 |   case EST_None: | 
 | 12644 |     break; | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12645 |      | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12646 |   case EST_ComputedNoexcept: | 
 | 12647 |     if (!Finder.TraverseStmt(Proto->getNoexceptExpr())) | 
 | 12648 |       return true; | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12649 |      | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12650 |   case EST_Dynamic: | 
 | 12651 |     for (FunctionProtoType::exception_iterator E = Proto->exception_begin(), | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12652 |          EEnd = Proto->exception_end(); | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12653 |          E != EEnd; ++E) { | 
 | 12654 |       if (!Finder.TraverseType(*E)) | 
 | 12655 |         return true; | 
 | 12656 |     } | 
 | 12657 |     break; | 
 | 12658 |   } | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12659 |  | 
 | 12660 |   return false; | 
| Douglas Gregor | cefc3af | 2012-04-16 07:05:22 +0000 | [diff] [blame] | 12661 | } | 
 | 12662 |  | 
 | 12663 | bool Sema::checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method) { | 
 | 12664 |   FindCXXThisExpr Finder(*this); | 
 | 12665 |  | 
 | 12666 |   // Check attributes. | 
 | 12667 |   for (Decl::attr_iterator A = Method->attr_begin(), AEnd = Method->attr_end(); | 
 | 12668 |        A != AEnd; ++A) { | 
 | 12669 |     // FIXME: This should be emitted by tblgen. | 
 | 12670 |     Expr *Arg = 0; | 
 | 12671 |     ArrayRef<Expr *> Args; | 
 | 12672 |     if (GuardedByAttr *G = dyn_cast<GuardedByAttr>(*A)) | 
 | 12673 |       Arg = G->getArg(); | 
 | 12674 |     else if (PtGuardedByAttr *G = dyn_cast<PtGuardedByAttr>(*A)) | 
 | 12675 |       Arg = G->getArg(); | 
 | 12676 |     else if (AcquiredAfterAttr *AA = dyn_cast<AcquiredAfterAttr>(*A)) | 
 | 12677 |       Args = ArrayRef<Expr *>(AA->args_begin(), AA->args_size()); | 
 | 12678 |     else if (AcquiredBeforeAttr *AB = dyn_cast<AcquiredBeforeAttr>(*A)) | 
 | 12679 |       Args = ArrayRef<Expr *>(AB->args_begin(), AB->args_size()); | 
 | 12680 |     else if (ExclusiveLockFunctionAttr *ELF  | 
 | 12681 |                = dyn_cast<ExclusiveLockFunctionAttr>(*A)) | 
 | 12682 |       Args = ArrayRef<Expr *>(ELF->args_begin(), ELF->args_size()); | 
 | 12683 |     else if (SharedLockFunctionAttr *SLF  | 
 | 12684 |                = dyn_cast<SharedLockFunctionAttr>(*A)) | 
 | 12685 |       Args = ArrayRef<Expr *>(SLF->args_begin(), SLF->args_size()); | 
 | 12686 |     else if (ExclusiveTrylockFunctionAttr *ETLF | 
 | 12687 |                = dyn_cast<ExclusiveTrylockFunctionAttr>(*A)) { | 
 | 12688 |       Arg = ETLF->getSuccessValue(); | 
 | 12689 |       Args = ArrayRef<Expr *>(ETLF->args_begin(), ETLF->args_size()); | 
 | 12690 |     } else if (SharedTrylockFunctionAttr *STLF | 
 | 12691 |                  = dyn_cast<SharedTrylockFunctionAttr>(*A)) { | 
 | 12692 |       Arg = STLF->getSuccessValue(); | 
 | 12693 |       Args = ArrayRef<Expr *>(STLF->args_begin(), STLF->args_size()); | 
 | 12694 |     } else if (UnlockFunctionAttr *UF = dyn_cast<UnlockFunctionAttr>(*A)) | 
 | 12695 |       Args = ArrayRef<Expr *>(UF->args_begin(), UF->args_size()); | 
 | 12696 |     else if (LockReturnedAttr *LR = dyn_cast<LockReturnedAttr>(*A)) | 
 | 12697 |       Arg = LR->getArg(); | 
 | 12698 |     else if (LocksExcludedAttr *LE = dyn_cast<LocksExcludedAttr>(*A)) | 
 | 12699 |       Args = ArrayRef<Expr *>(LE->args_begin(), LE->args_size()); | 
 | 12700 |     else if (ExclusiveLocksRequiredAttr *ELR  | 
 | 12701 |                = dyn_cast<ExclusiveLocksRequiredAttr>(*A)) | 
 | 12702 |       Args = ArrayRef<Expr *>(ELR->args_begin(), ELR->args_size()); | 
 | 12703 |     else if (SharedLocksRequiredAttr *SLR  | 
 | 12704 |                = dyn_cast<SharedLocksRequiredAttr>(*A)) | 
 | 12705 |       Args = ArrayRef<Expr *>(SLR->args_begin(), SLR->args_size()); | 
 | 12706 |  | 
 | 12707 |     if (Arg && !Finder.TraverseStmt(Arg)) | 
 | 12708 |       return true; | 
 | 12709 |      | 
 | 12710 |     for (unsigned I = 0, N = Args.size(); I != N; ++I) { | 
 | 12711 |       if (!Finder.TraverseStmt(Args[I])) | 
 | 12712 |         return true; | 
 | 12713 |     } | 
 | 12714 |   } | 
 | 12715 |    | 
 | 12716 |   return false; | 
 | 12717 | } | 
 | 12718 |  | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12719 | void | 
 | 12720 | Sema::checkExceptionSpecification(ExceptionSpecificationType EST, | 
 | 12721 |                                   ArrayRef<ParsedType> DynamicExceptions, | 
 | 12722 |                                   ArrayRef<SourceRange> DynamicExceptionRanges, | 
 | 12723 |                                   Expr *NoexceptExpr, | 
| Dmitri Gribenko | cfa88f8 | 2013-01-12 19:30:44 +0000 | [diff] [blame] | 12724 |                                   SmallVectorImpl<QualType> &Exceptions, | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12725 |                                   FunctionProtoType::ExtProtoInfo &EPI) { | 
 | 12726 |   Exceptions.clear(); | 
 | 12727 |   EPI.ExceptionSpecType = EST; | 
 | 12728 |   if (EST == EST_Dynamic) { | 
 | 12729 |     Exceptions.reserve(DynamicExceptions.size()); | 
 | 12730 |     for (unsigned ei = 0, ee = DynamicExceptions.size(); ei != ee; ++ei) { | 
 | 12731 |       // FIXME: Preserve type source info. | 
 | 12732 |       QualType ET = GetTypeFromParser(DynamicExceptions[ei]); | 
 | 12733 |  | 
 | 12734 |       SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
 | 12735 |       collectUnexpandedParameterPacks(ET, Unexpanded); | 
 | 12736 |       if (!Unexpanded.empty()) { | 
 | 12737 |         DiagnoseUnexpandedParameterPacks(DynamicExceptionRanges[ei].getBegin(), | 
 | 12738 |                                          UPPC_ExceptionType, | 
 | 12739 |                                          Unexpanded); | 
 | 12740 |         continue; | 
 | 12741 |       } | 
 | 12742 |  | 
 | 12743 |       // Check that the type is valid for an exception spec, and | 
 | 12744 |       // drop it if not. | 
 | 12745 |       if (!CheckSpecifiedExceptionType(ET, DynamicExceptionRanges[ei])) | 
 | 12746 |         Exceptions.push_back(ET); | 
 | 12747 |     } | 
 | 12748 |     EPI.NumExceptions = Exceptions.size(); | 
 | 12749 |     EPI.Exceptions = Exceptions.data(); | 
 | 12750 |     return; | 
 | 12751 |   } | 
 | 12752 |    | 
 | 12753 |   if (EST == EST_ComputedNoexcept) { | 
 | 12754 |     // If an error occurred, there's no expression here. | 
 | 12755 |     if (NoexceptExpr) { | 
 | 12756 |       assert((NoexceptExpr->isTypeDependent() || | 
 | 12757 |               NoexceptExpr->getType()->getCanonicalTypeUnqualified() == | 
 | 12758 |               Context.BoolTy) && | 
 | 12759 |              "Parser should have made sure that the expression is boolean"); | 
 | 12760 |       if (NoexceptExpr && DiagnoseUnexpandedParameterPack(NoexceptExpr)) { | 
 | 12761 |         EPI.ExceptionSpecType = EST_BasicNoexcept; | 
 | 12762 |         return; | 
 | 12763 |       } | 
 | 12764 |        | 
 | 12765 |       if (!NoexceptExpr->isValueDependent()) | 
 | 12766 |         NoexceptExpr = VerifyIntegerConstantExpression(NoexceptExpr, 0, | 
| Douglas Gregor | ab41fe9 | 2012-05-04 22:38:52 +0000 | [diff] [blame] | 12767 |                          diag::err_noexcept_needs_constant_expression, | 
| Douglas Gregor | 74e2fc3 | 2012-04-16 18:27:27 +0000 | [diff] [blame] | 12768 |                          /*AllowFold*/ false).take(); | 
 | 12769 |       EPI.NoexceptExpr = NoexceptExpr; | 
 | 12770 |     } | 
 | 12771 |     return; | 
 | 12772 |   } | 
 | 12773 | } | 
 | 12774 |  | 
| Peter Collingbourne | 78dd67e | 2011-10-02 23:49:40 +0000 | [diff] [blame] | 12775 | /// IdentifyCUDATarget - Determine the CUDA compilation target for this function | 
 | 12776 | Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D) { | 
 | 12777 |   // Implicitly declared functions (e.g. copy constructors) are | 
 | 12778 |   // __host__ __device__ | 
 | 12779 |   if (D->isImplicit()) | 
 | 12780 |     return CFT_HostDevice; | 
 | 12781 |  | 
 | 12782 |   if (D->hasAttr<CUDAGlobalAttr>()) | 
 | 12783 |     return CFT_Global; | 
 | 12784 |  | 
 | 12785 |   if (D->hasAttr<CUDADeviceAttr>()) { | 
 | 12786 |     if (D->hasAttr<CUDAHostAttr>()) | 
 | 12787 |       return CFT_HostDevice; | 
| Benjamin Kramer | 4c7736e | 2013-07-24 15:28:33 +0000 | [diff] [blame] | 12788 |     return CFT_Device; | 
| Peter Collingbourne | 78dd67e | 2011-10-02 23:49:40 +0000 | [diff] [blame] | 12789 |   } | 
 | 12790 |  | 
 | 12791 |   return CFT_Host; | 
 | 12792 | } | 
 | 12793 |  | 
 | 12794 | bool Sema::CheckCUDATarget(CUDAFunctionTarget CallerTarget, | 
 | 12795 |                            CUDAFunctionTarget CalleeTarget) { | 
 | 12796 |   // CUDA B.1.1 "The __device__ qualifier declares a function that is... | 
 | 12797 |   // Callable from the device only." | 
 | 12798 |   if (CallerTarget == CFT_Host && CalleeTarget == CFT_Device) | 
 | 12799 |     return true; | 
 | 12800 |  | 
 | 12801 |   // CUDA B.1.2 "The __global__ qualifier declares a function that is... | 
 | 12802 |   // Callable from the host only." | 
 | 12803 |   // CUDA B.1.3 "The __host__ qualifier declares a function that is... | 
 | 12804 |   // Callable from the host only." | 
 | 12805 |   if ((CallerTarget == CFT_Device || CallerTarget == CFT_Global) && | 
 | 12806 |       (CalleeTarget == CFT_Host || CalleeTarget == CFT_Global)) | 
 | 12807 |     return true; | 
 | 12808 |  | 
 | 12809 |   if (CallerTarget == CFT_HostDevice && CalleeTarget != CFT_HostDevice) | 
 | 12810 |     return true; | 
 | 12811 |  | 
 | 12812 |   return false; | 
 | 12813 | } | 
| John McCall | 76da55d | 2013-04-16 07:28:30 +0000 | [diff] [blame] | 12814 |  | 
 | 12815 | /// HandleMSProperty - Analyze a __delcspec(property) field of a C++ class. | 
 | 12816 | /// | 
 | 12817 | MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record, | 
 | 12818 |                                        SourceLocation DeclStart, | 
 | 12819 |                                        Declarator &D, Expr *BitWidth, | 
 | 12820 |                                        InClassInitStyle InitStyle, | 
 | 12821 |                                        AccessSpecifier AS, | 
 | 12822 |                                        AttributeList *MSPropertyAttr) { | 
 | 12823 |   IdentifierInfo *II = D.getIdentifier(); | 
 | 12824 |   if (!II) { | 
 | 12825 |     Diag(DeclStart, diag::err_anonymous_property); | 
 | 12826 |     return NULL; | 
 | 12827 |   } | 
 | 12828 |   SourceLocation Loc = D.getIdentifierLoc(); | 
 | 12829 |  | 
 | 12830 |   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); | 
 | 12831 |   QualType T = TInfo->getType(); | 
 | 12832 |   if (getLangOpts().CPlusPlus) { | 
 | 12833 |     CheckExtraCXXDefaultArguments(D); | 
 | 12834 |  | 
 | 12835 |     if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo, | 
 | 12836 |                                         UPPC_DataMemberType)) { | 
 | 12837 |       D.setInvalidType(); | 
 | 12838 |       T = Context.IntTy; | 
 | 12839 |       TInfo = Context.getTrivialTypeSourceInfo(T, Loc); | 
 | 12840 |     } | 
 | 12841 |   } | 
 | 12842 |  | 
 | 12843 |   DiagnoseFunctionSpecifiers(D.getDeclSpec()); | 
 | 12844 |  | 
 | 12845 |   if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) | 
 | 12846 |     Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), | 
 | 12847 |          diag::err_invalid_thread) | 
 | 12848 |       << DeclSpec::getSpecifierName(TSCS); | 
 | 12849 |  | 
 | 12850 |   // Check to see if this name was declared as a member previously | 
 | 12851 |   NamedDecl *PrevDecl = 0; | 
 | 12852 |   LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration); | 
 | 12853 |   LookupName(Previous, S); | 
 | 12854 |   switch (Previous.getResultKind()) { | 
 | 12855 |   case LookupResult::Found: | 
 | 12856 |   case LookupResult::FoundUnresolvedValue: | 
 | 12857 |     PrevDecl = Previous.getAsSingle<NamedDecl>(); | 
 | 12858 |     break; | 
 | 12859 |  | 
 | 12860 |   case LookupResult::FoundOverloaded: | 
 | 12861 |     PrevDecl = Previous.getRepresentativeDecl(); | 
 | 12862 |     break; | 
 | 12863 |  | 
 | 12864 |   case LookupResult::NotFound: | 
 | 12865 |   case LookupResult::NotFoundInCurrentInstantiation: | 
 | 12866 |   case LookupResult::Ambiguous: | 
 | 12867 |     break; | 
 | 12868 |   } | 
 | 12869 |  | 
 | 12870 |   if (PrevDecl && PrevDecl->isTemplateParameter()) { | 
 | 12871 |     // Maybe we will complain about the shadowed template parameter. | 
 | 12872 |     DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); | 
 | 12873 |     // Just pretend that we didn't see the previous declaration. | 
 | 12874 |     PrevDecl = 0; | 
 | 12875 |   } | 
 | 12876 |  | 
 | 12877 |   if (PrevDecl && !isDeclInScope(PrevDecl, Record, S)) | 
 | 12878 |     PrevDecl = 0; | 
 | 12879 |  | 
 | 12880 |   SourceLocation TSSL = D.getLocStart(); | 
 | 12881 |   MSPropertyDecl *NewPD; | 
 | 12882 |   const AttributeList::PropertyData &Data = MSPropertyAttr->getPropertyData(); | 
 | 12883 |   NewPD = new (Context) MSPropertyDecl(Record, Loc, | 
 | 12884 |                                        II, T, TInfo, TSSL, | 
 | 12885 |                                        Data.GetterId, Data.SetterId); | 
 | 12886 |   ProcessDeclAttributes(TUScope, NewPD, D); | 
 | 12887 |   NewPD->setAccess(AS); | 
 | 12888 |  | 
 | 12889 |   if (NewPD->isInvalidDecl()) | 
 | 12890 |     Record->setInvalidDecl(); | 
 | 12891 |  | 
 | 12892 |   if (D.getDeclSpec().isModulePrivateSpecified()) | 
 | 12893 |     NewPD->setModulePrivate(); | 
 | 12894 |  | 
 | 12895 |   if (NewPD->isInvalidDecl() && PrevDecl) { | 
 | 12896 |     // Don't introduce NewFD into scope; there's already something | 
 | 12897 |     // with the same name in the same scope. | 
 | 12898 |   } else if (II) { | 
 | 12899 |     PushOnScopeChains(NewPD, S); | 
 | 12900 |   } else | 
 | 12901 |     Record->addDecl(NewPD); | 
 | 12902 |  | 
 | 12903 |   return NewPD; | 
 | 12904 | } |