| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 1 | //===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 0bc735f | 2007-12-29 19:59:25 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | //  This file implements semantic analysis for C++ expressions. | 
 | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
| John McCall | 2d88708 | 2010-08-25 22:03:47 +0000 | [diff] [blame] | 14 | #include "clang/Sema/SemaInternal.h" | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 15 | #include "clang/Sema/DeclSpec.h" | 
| Douglas Gregor | e737f50 | 2010-08-12 20:07:10 +0000 | [diff] [blame] | 16 | #include "clang/Sema/Initialization.h" | 
 | 17 | #include "clang/Sema/Lookup.h" | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 18 | #include "clang/Sema/ParsedTemplate.h" | 
| John McCall | 469a1eb | 2011-02-02 13:00:07 +0000 | [diff] [blame] | 19 | #include "clang/Sema/ScopeInfo.h" | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 20 | #include "clang/Sema/Scope.h" | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 21 | #include "clang/Sema/TemplateDeduction.h" | 
| Steve Naroff | 210679c | 2007-08-25 14:02:58 +0000 | [diff] [blame] | 22 | #include "clang/AST/ASTContext.h" | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 23 | #include "clang/AST/CXXInheritance.h" | 
| John McCall | 7cd088e | 2010-08-24 07:21:54 +0000 | [diff] [blame] | 24 | #include "clang/AST/DeclObjC.h" | 
| Anders Carlsson | d497ba7 | 2009-08-26 22:59:12 +0000 | [diff] [blame] | 25 | #include "clang/AST/ExprCXX.h" | 
| Fariborz Jahanian | d426662 | 2010-06-16 18:56:04 +0000 | [diff] [blame] | 26 | #include "clang/AST/ExprObjC.h" | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 27 | #include "clang/AST/TypeLoc.h" | 
| Anders Carlsson | d497ba7 | 2009-08-26 22:59:12 +0000 | [diff] [blame] | 28 | #include "clang/Basic/PartialDiagnostic.h" | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 29 | #include "clang/Basic/TargetInfo.h" | 
| Anders Carlsson | d497ba7 | 2009-08-26 22:59:12 +0000 | [diff] [blame] | 30 | #include "clang/Lex/Preprocessor.h" | 
| Douglas Gregor | 3fc749d | 2008-12-23 00:26:44 +0000 | [diff] [blame] | 31 | #include "llvm/ADT/STLExtras.h" | 
| Chandler Carruth | 73e0a91 | 2011-05-01 07:23:17 +0000 | [diff] [blame] | 32 | #include "llvm/Support/ErrorHandling.h" | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 33 | using namespace clang; | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 34 | using namespace sema; | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 35 |  | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 36 | ParsedType Sema::getDestructorName(SourceLocation TildeLoc, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 37 |                                    IdentifierInfo &II, | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 38 |                                    SourceLocation NameLoc, | 
 | 39 |                                    Scope *S, CXXScopeSpec &SS, | 
 | 40 |                                    ParsedType ObjectTypePtr, | 
 | 41 |                                    bool EnteringContext) { | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 42 |   // Determine where to perform name lookup. | 
 | 43 |  | 
 | 44 |   // FIXME: This area of the standard is very messy, and the current | 
 | 45 |   // wording is rather unclear about which scopes we search for the | 
 | 46 |   // destructor name; see core issues 399 and 555. Issue 399 in | 
 | 47 |   // particular shows where the current description of destructor name | 
 | 48 |   // lookup is completely out of line with existing practice, e.g., | 
 | 49 |   // this appears to be ill-formed: | 
 | 50 |   // | 
 | 51 |   //   namespace N { | 
 | 52 |   //     template <typename T> struct S { | 
 | 53 |   //       ~S(); | 
 | 54 |   //     }; | 
 | 55 |   //   } | 
 | 56 |   // | 
 | 57 |   //   void f(N::S<int>* s) { | 
 | 58 |   //     s->N::S<int>::~S(); | 
 | 59 |   //   } | 
 | 60 |   // | 
| Douglas Gregor | 93649fd | 2010-02-23 00:15:22 +0000 | [diff] [blame] | 61 |   // See also PR6358 and PR6359. | 
| Sebastian Redl | c0fee50 | 2010-07-07 23:17:38 +0000 | [diff] [blame] | 62 |   // For this reason, we're currently only doing the C++03 version of this | 
 | 63 |   // code; the C++0x version has to wait until we get a proper spec. | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 64 |   QualType SearchType; | 
 | 65 |   DeclContext *LookupCtx = 0; | 
 | 66 |   bool isDependent = false; | 
 | 67 |   bool LookInScope = false; | 
 | 68 |  | 
 | 69 |   // If we have an object type, it's because we are in a | 
 | 70 |   // pseudo-destructor-expression or a member access expression, and | 
 | 71 |   // we know what type we're looking for. | 
 | 72 |   if (ObjectTypePtr) | 
 | 73 |     SearchType = GetTypeFromParser(ObjectTypePtr); | 
 | 74 |  | 
 | 75 |   if (SS.isSet()) { | 
| Douglas Gregor | 93649fd | 2010-02-23 00:15:22 +0000 | [diff] [blame] | 76 |     NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 77 |  | 
| Douglas Gregor | 93649fd | 2010-02-23 00:15:22 +0000 | [diff] [blame] | 78 |     bool AlreadySearched = false; | 
 | 79 |     bool LookAtPrefix = true; | 
| Sebastian Redl | c0fee50 | 2010-07-07 23:17:38 +0000 | [diff] [blame] | 80 |     // C++ [basic.lookup.qual]p6: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 81 |     //   If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier, | 
| Sebastian Redl | c0fee50 | 2010-07-07 23:17:38 +0000 | [diff] [blame] | 82 |     //   the type-names are looked up as types in the scope designated by the | 
 | 83 |     //   nested-name-specifier. In a qualified-id of the form: | 
| NAKAMURA Takumi | 0099530 | 2011-01-27 07:09:49 +0000 | [diff] [blame] | 84 |     // | 
 | 85 |     //     ::[opt] nested-name-specifier  ~ class-name | 
| Sebastian Redl | c0fee50 | 2010-07-07 23:17:38 +0000 | [diff] [blame] | 86 |     // | 
 | 87 |     //   where the nested-name-specifier designates a namespace scope, and in | 
| Chandler Carruth | 5e895a8 | 2010-02-21 10:19:54 +0000 | [diff] [blame] | 88 |     //   a qualified-id of the form: | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 89 |     // | 
| NAKAMURA Takumi | 0099530 | 2011-01-27 07:09:49 +0000 | [diff] [blame] | 90 |     //     ::opt nested-name-specifier class-name ::  ~ class-name | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 91 |     // | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 92 |     //   the class-names are looked up as types in the scope designated by | 
| Sebastian Redl | c0fee50 | 2010-07-07 23:17:38 +0000 | [diff] [blame] | 93 |     //   the nested-name-specifier. | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 94 |     // | 
| Sebastian Redl | c0fee50 | 2010-07-07 23:17:38 +0000 | [diff] [blame] | 95 |     // Here, we check the first case (completely) and determine whether the | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 96 |     // code below is permitted to look at the prefix of the | 
| Sebastian Redl | c0fee50 | 2010-07-07 23:17:38 +0000 | [diff] [blame] | 97 |     // nested-name-specifier. | 
 | 98 |     DeclContext *DC = computeDeclContext(SS, EnteringContext); | 
 | 99 |     if (DC && DC->isFileContext()) { | 
 | 100 |       AlreadySearched = true; | 
 | 101 |       LookupCtx = DC; | 
 | 102 |       isDependent = false; | 
 | 103 |     } else if (DC && isa<CXXRecordDecl>(DC)) | 
 | 104 |       LookAtPrefix = false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 105 |  | 
| Sebastian Redl | c0fee50 | 2010-07-07 23:17:38 +0000 | [diff] [blame] | 106 |     // The second case from the C++03 rules quoted further above. | 
| Douglas Gregor | 93649fd | 2010-02-23 00:15:22 +0000 | [diff] [blame] | 107 |     NestedNameSpecifier *Prefix = 0; | 
 | 108 |     if (AlreadySearched) { | 
 | 109 |       // Nothing left to do. | 
 | 110 |     } else if (LookAtPrefix && (Prefix = NNS->getPrefix())) { | 
 | 111 |       CXXScopeSpec PrefixSS; | 
| Douglas Gregor | 7e38494 | 2011-02-25 16:07:42 +0000 | [diff] [blame] | 112 |       PrefixSS.Adopt(NestedNameSpecifierLoc(Prefix, SS.location_data())); | 
| Douglas Gregor | 93649fd | 2010-02-23 00:15:22 +0000 | [diff] [blame] | 113 |       LookupCtx = computeDeclContext(PrefixSS, EnteringContext); | 
 | 114 |       isDependent = isDependentScopeSpecifier(PrefixSS); | 
| Douglas Gregor | 93649fd | 2010-02-23 00:15:22 +0000 | [diff] [blame] | 115 |     } else if (ObjectTypePtr) { | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 116 |       LookupCtx = computeDeclContext(SearchType); | 
 | 117 |       isDependent = SearchType->isDependentType(); | 
 | 118 |     } else { | 
 | 119 |       LookupCtx = computeDeclContext(SS, EnteringContext); | 
| Douglas Gregor | 93649fd | 2010-02-23 00:15:22 +0000 | [diff] [blame] | 120 |       isDependent = LookupCtx && LookupCtx->isDependentContext(); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 121 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 122 |  | 
| Douglas Gregor | edc9050 | 2010-02-25 04:46:04 +0000 | [diff] [blame] | 123 |     LookInScope = false; | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 124 |   } else if (ObjectTypePtr) { | 
 | 125 |     // C++ [basic.lookup.classref]p3: | 
 | 126 |     //   If the unqualified-id is ~type-name, the type-name is looked up | 
 | 127 |     //   in the context of the entire postfix-expression. If the type T | 
 | 128 |     //   of the object expression is of a class type C, the type-name is | 
 | 129 |     //   also looked up in the scope of class C. At least one of the | 
 | 130 |     //   lookups shall find a name that refers to (possibly | 
 | 131 |     //   cv-qualified) T. | 
 | 132 |     LookupCtx = computeDeclContext(SearchType); | 
 | 133 |     isDependent = SearchType->isDependentType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 134 |     assert((isDependent || !SearchType->isIncompleteType()) && | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 135 |            "Caller should have completed object type"); | 
 | 136 |  | 
 | 137 |     LookInScope = true; | 
 | 138 |   } else { | 
 | 139 |     // Perform lookup into the current scope (only). | 
 | 140 |     LookInScope = true; | 
 | 141 |   } | 
 | 142 |  | 
| Douglas Gregor | 7ec1873 | 2011-03-04 22:32:08 +0000 | [diff] [blame] | 143 |   TypeDecl *NonMatchingTypeDecl = 0; | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 144 |   LookupResult Found(*this, &II, NameLoc, LookupOrdinaryName); | 
 | 145 |   for (unsigned Step = 0; Step != 2; ++Step) { | 
 | 146 |     // Look for the name first in the computed lookup context (if we | 
| Douglas Gregor | 7ec1873 | 2011-03-04 22:32:08 +0000 | [diff] [blame] | 147 |     // have one) and, if that fails to find a match, in the scope (if | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 148 |     // we're allowed to look there). | 
 | 149 |     Found.clear(); | 
 | 150 |     if (Step == 0 && LookupCtx) | 
 | 151 |       LookupQualifiedName(Found, LookupCtx); | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 152 |     else if (Step == 1 && LookInScope && S) | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 153 |       LookupName(Found, S); | 
 | 154 |     else | 
 | 155 |       continue; | 
 | 156 |  | 
 | 157 |     // FIXME: Should we be suppressing ambiguities here? | 
 | 158 |     if (Found.isAmbiguous()) | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 159 |       return ParsedType(); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 160 |  | 
 | 161 |     if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) { | 
 | 162 |       QualType T = Context.getTypeDeclType(Type); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 163 |  | 
 | 164 |       if (SearchType.isNull() || SearchType->isDependentType() || | 
 | 165 |           Context.hasSameUnqualifiedType(T, SearchType)) { | 
 | 166 |         // We found our type! | 
 | 167 |  | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 168 |         return ParsedType::make(T); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 169 |       } | 
| John Wiegley | 36784e7 | 2011-03-08 08:13:22 +0000 | [diff] [blame] | 170 |  | 
| Douglas Gregor | 7ec1873 | 2011-03-04 22:32:08 +0000 | [diff] [blame] | 171 |       if (!SearchType.isNull()) | 
 | 172 |         NonMatchingTypeDecl = Type; | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 173 |     } | 
 | 174 |  | 
 | 175 |     // If the name that we found is a class template name, and it is | 
 | 176 |     // the same name as the template name in the last part of the | 
 | 177 |     // nested-name-specifier (if present) or the object type, then | 
 | 178 |     // this is the destructor for that class. | 
 | 179 |     // FIXME: This is a workaround until we get real drafting for core | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 180 |     // issue 399, for which there isn't even an obvious direction. | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 181 |     if (ClassTemplateDecl *Template = Found.getAsSingle<ClassTemplateDecl>()) { | 
 | 182 |       QualType MemberOfType; | 
 | 183 |       if (SS.isSet()) { | 
 | 184 |         if (DeclContext *Ctx = computeDeclContext(SS, EnteringContext)) { | 
 | 185 |           // Figure out the type of the context, if it has one. | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 186 |           if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) | 
 | 187 |             MemberOfType = Context.getTypeDeclType(Record); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 188 |         } | 
 | 189 |       } | 
 | 190 |       if (MemberOfType.isNull()) | 
 | 191 |         MemberOfType = SearchType; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 192 |  | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 193 |       if (MemberOfType.isNull()) | 
 | 194 |         continue; | 
 | 195 |  | 
 | 196 |       // We're referring into a class template specialization. If the | 
 | 197 |       // class template we found is the same as the template being | 
 | 198 |       // specialized, we found what we are looking for. | 
 | 199 |       if (const RecordType *Record = MemberOfType->getAs<RecordType>()) { | 
 | 200 |         if (ClassTemplateSpecializationDecl *Spec | 
 | 201 |               = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) { | 
 | 202 |           if (Spec->getSpecializedTemplate()->getCanonicalDecl() == | 
 | 203 |                 Template->getCanonicalDecl()) | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 204 |             return ParsedType::make(MemberOfType); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 205 |         } | 
 | 206 |  | 
 | 207 |         continue; | 
 | 208 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 209 |  | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 210 |       // We're referring to an unresolved class template | 
 | 211 |       // specialization. Determine whether we class template we found | 
 | 212 |       // is the same as the template being specialized or, if we don't | 
 | 213 |       // know which template is being specialized, that it at least | 
 | 214 |       // has the same name. | 
 | 215 |       if (const TemplateSpecializationType *SpecType | 
 | 216 |             = MemberOfType->getAs<TemplateSpecializationType>()) { | 
 | 217 |         TemplateName SpecName = SpecType->getTemplateName(); | 
 | 218 |  | 
 | 219 |         // The class template we found is the same template being | 
 | 220 |         // specialized. | 
 | 221 |         if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) { | 
 | 222 |           if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl()) | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 223 |             return ParsedType::make(MemberOfType); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 224 |  | 
 | 225 |           continue; | 
 | 226 |         } | 
 | 227 |  | 
 | 228 |         // The class template we found has the same name as the | 
 | 229 |         // (dependent) template name being specialized. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 230 |         if (DependentTemplateName *DepTemplate | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 231 |                                     = SpecName.getAsDependentTemplateName()) { | 
 | 232 |           if (DepTemplate->isIdentifier() && | 
 | 233 |               DepTemplate->getIdentifier() == Template->getIdentifier()) | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 234 |             return ParsedType::make(MemberOfType); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 235 |  | 
 | 236 |           continue; | 
 | 237 |         } | 
 | 238 |       } | 
 | 239 |     } | 
 | 240 |   } | 
 | 241 |  | 
 | 242 |   if (isDependent) { | 
 | 243 |     // We didn't find our type, but that's okay: it's dependent | 
 | 244 |     // anyway. | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 245 |      | 
 | 246 |     // FIXME: What if we have no nested-name-specifier? | 
 | 247 |     QualType T = CheckTypenameType(ETK_None, SourceLocation(), | 
 | 248 |                                    SS.getWithLocInContext(Context), | 
 | 249 |                                    II, NameLoc); | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 250 |     return ParsedType::make(T); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 251 |   } | 
 | 252 |  | 
| Douglas Gregor | 7ec1873 | 2011-03-04 22:32:08 +0000 | [diff] [blame] | 253 |   if (NonMatchingTypeDecl) { | 
 | 254 |     QualType T = Context.getTypeDeclType(NonMatchingTypeDecl); | 
 | 255 |     Diag(NameLoc, diag::err_destructor_expr_type_mismatch) | 
 | 256 |       << T << SearchType; | 
 | 257 |     Diag(NonMatchingTypeDecl->getLocation(), diag::note_destructor_type_here) | 
 | 258 |       << T; | 
 | 259 |   } else if (ObjectTypePtr) | 
 | 260 |     Diag(NameLoc, diag::err_ident_in_dtor_not_a_type) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 261 |       << &II; | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 262 |   else | 
 | 263 |     Diag(NameLoc, diag::err_destructor_class_name); | 
 | 264 |  | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 265 |   return ParsedType(); | 
| Douglas Gregor | 124b878 | 2010-02-16 19:09:40 +0000 | [diff] [blame] | 266 | } | 
 | 267 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 268 | /// \brief Build a C++ typeid expression with a type operand. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 269 | ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, | 
| Douglas Gregor | 4eb4f0f | 2010-09-08 23:14:30 +0000 | [diff] [blame] | 270 |                                 SourceLocation TypeidLoc, | 
 | 271 |                                 TypeSourceInfo *Operand, | 
 | 272 |                                 SourceLocation RParenLoc) { | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 273 |   // C++ [expr.typeid]p4: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 274 |   //   The top-level cv-qualifiers of the lvalue expression or the type-id | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 275 |   //   that is the operand of typeid are always ignored. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 276 |   //   If the type of the type-id is a class type or a reference to a class | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 277 |   //   type, the class shall be completely-defined. | 
| Douglas Gregor | d1c1d7b | 2010-06-02 06:16:02 +0000 | [diff] [blame] | 278 |   Qualifiers Quals; | 
 | 279 |   QualType T | 
 | 280 |     = Context.getUnqualifiedArrayType(Operand->getType().getNonReferenceType(), | 
 | 281 |                                       Quals); | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 282 |   if (T->getAs<RecordType>() && | 
 | 283 |       RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid)) | 
 | 284 |     return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 285 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 286 |   return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(), | 
 | 287 |                                            Operand, | 
 | 288 |                                            SourceRange(TypeidLoc, RParenLoc))); | 
 | 289 | } | 
 | 290 |  | 
 | 291 | /// \brief Build a C++ typeid expression with an expression operand. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 292 | ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, | 
| Douglas Gregor | 4eb4f0f | 2010-09-08 23:14:30 +0000 | [diff] [blame] | 293 |                                 SourceLocation TypeidLoc, | 
 | 294 |                                 Expr *E, | 
 | 295 |                                 SourceLocation RParenLoc) { | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 296 |   bool isUnevaluatedOperand = true; | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 297 |   if (E && !E->isTypeDependent()) { | 
| John McCall | 6dbba4f | 2011-10-11 23:14:30 +0000 | [diff] [blame] | 298 |     if (E->getType()->isPlaceholderType()) { | 
 | 299 |       ExprResult result = CheckPlaceholderExpr(E); | 
 | 300 |       if (result.isInvalid()) return ExprError(); | 
 | 301 |       E = result.take(); | 
 | 302 |     } | 
 | 303 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 304 |     QualType T = E->getType(); | 
 | 305 |     if (const RecordType *RecordT = T->getAs<RecordType>()) { | 
 | 306 |       CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl()); | 
 | 307 |       // C++ [expr.typeid]p3: | 
 | 308 |       //   [...] If the type of the expression is a class type, the class | 
 | 309 |       //   shall be completely-defined. | 
 | 310 |       if (RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid)) | 
 | 311 |         return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 312 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 313 |       // C++ [expr.typeid]p3: | 
| Sebastian Redl | 906082e | 2010-07-20 04:20:21 +0000 | [diff] [blame] | 314 |       //   When typeid is applied to an expression other than an glvalue of a | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 315 |       //   polymorphic class type [...] [the] expression is an unevaluated | 
 | 316 |       //   operand. [...] | 
| Sebastian Redl | 906082e | 2010-07-20 04:20:21 +0000 | [diff] [blame] | 317 |       if (RecordD->isPolymorphic() && E->Classify(Context).isGLValue()) { | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 318 |         isUnevaluatedOperand = false; | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 319 |  | 
 | 320 |         // We require a vtable to query the type at run time. | 
 | 321 |         MarkVTableUsed(TypeidLoc, RecordD); | 
 | 322 |       } | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 323 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 324 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 325 |     // C++ [expr.typeid]p4: | 
 | 326 |     //   [...] If the type of the type-id is a reference to a possibly | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 327 |     //   cv-qualified type, the result of the typeid expression refers to a | 
 | 328 |     //   std::type_info object representing the cv-unqualified referenced | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 329 |     //   type. | 
| Douglas Gregor | d1c1d7b | 2010-06-02 06:16:02 +0000 | [diff] [blame] | 330 |     Qualifiers Quals; | 
 | 331 |     QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals); | 
 | 332 |     if (!Context.hasSameType(T, UnqualT)) { | 
 | 333 |       T = UnqualT; | 
| Eli Friedman | c1c0dfb | 2011-09-27 21:58:52 +0000 | [diff] [blame] | 334 |       E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).take(); | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 335 |     } | 
 | 336 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 337 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 338 |   // If this is an unevaluated operand, clear out the set of | 
 | 339 |   // declaration references we have been computing and eliminate any | 
 | 340 |   // temporaries introduced in its computation. | 
 | 341 |   if (isUnevaluatedOperand) | 
 | 342 |     ExprEvalContexts.back().Context = Unevaluated; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 343 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 344 |   return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(), | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 345 |                                            E, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 346 |                                            SourceRange(TypeidLoc, RParenLoc))); | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 347 | } | 
 | 348 |  | 
 | 349 | /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression); | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 350 | ExprResult | 
| Sebastian Redl | c42e118 | 2008-11-11 11:37:55 +0000 | [diff] [blame] | 351 | Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, | 
 | 352 |                      bool isType, void *TyOrExpr, SourceLocation RParenLoc) { | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 353 |   // Find the std::type_info type. | 
| Sebastian Redl | ce0682f | 2011-03-31 19:29:24 +0000 | [diff] [blame] | 354 |   if (!getStdNamespace()) | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 355 |     return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); | 
| Argyrios Kyrtzidis | e866190 | 2009-08-19 01:28:28 +0000 | [diff] [blame] | 356 |  | 
| Douglas Gregor | 4eb4f0f | 2010-09-08 23:14:30 +0000 | [diff] [blame] | 357 |   if (!CXXTypeInfoDecl) { | 
 | 358 |     IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info"); | 
 | 359 |     LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName); | 
 | 360 |     LookupQualifiedName(R, getStdNamespace()); | 
 | 361 |     CXXTypeInfoDecl = R.getAsSingle<RecordDecl>(); | 
 | 362 |     if (!CXXTypeInfoDecl) | 
 | 363 |       return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); | 
 | 364 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 365 |  | 
| Douglas Gregor | 4eb4f0f | 2010-09-08 23:14:30 +0000 | [diff] [blame] | 366 |   QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 367 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 368 |   if (isType) { | 
 | 369 |     // The operand is a type; handle it as such. | 
 | 370 |     TypeSourceInfo *TInfo = 0; | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 371 |     QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr), | 
 | 372 |                                    &TInfo); | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 373 |     if (T.isNull()) | 
 | 374 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 375 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 376 |     if (!TInfo) | 
 | 377 |       TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc); | 
| Sebastian Redl | c42e118 | 2008-11-11 11:37:55 +0000 | [diff] [blame] | 378 |  | 
| Douglas Gregor | 57fdc8a | 2010-04-26 22:37:10 +0000 | [diff] [blame] | 379 |     return BuildCXXTypeId(TypeInfoType, OpLoc, TInfo, RParenLoc); | 
| Douglas Gregor | ac7610d | 2009-06-22 20:57:11 +0000 | [diff] [blame] | 380 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 381 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 382 |   // The operand is an expression. | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 383 |   return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc); | 
| Sebastian Redl | c42e118 | 2008-11-11 11:37:55 +0000 | [diff] [blame] | 384 | } | 
 | 385 |  | 
| Francois Pichet | 6915c52 | 2010-12-27 01:32:00 +0000 | [diff] [blame] | 386 | /// Retrieve the UuidAttr associated with QT. | 
 | 387 | static UuidAttr *GetUuidAttrOfType(QualType QT) { | 
 | 388 |   // Optionally remove one level of pointer, reference or array indirection. | 
| John McCall | f4c7371 | 2011-01-19 06:33:43 +0000 | [diff] [blame] | 389 |   const Type *Ty = QT.getTypePtr();; | 
| Francois Pichet | 913b7bf | 2010-12-20 03:51:03 +0000 | [diff] [blame] | 390 |   if (QT->isPointerType() || QT->isReferenceType()) | 
 | 391 |     Ty = QT->getPointeeType().getTypePtr(); | 
 | 392 |   else if (QT->isArrayType()) | 
 | 393 |     Ty = cast<ArrayType>(QT)->getElementType().getTypePtr(); | 
 | 394 |  | 
| Francois Pichet | 8db75a2 | 2011-05-08 10:02:20 +0000 | [diff] [blame] | 395 |   // Loop all record redeclaration looking for an uuid attribute. | 
| Francois Pichet | 6915c52 | 2010-12-27 01:32:00 +0000 | [diff] [blame] | 396 |   CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); | 
| Francois Pichet | 8db75a2 | 2011-05-08 10:02:20 +0000 | [diff] [blame] | 397 |   for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(), | 
 | 398 |        E = RD->redecls_end(); I != E; ++I) { | 
 | 399 |     if (UuidAttr *Uuid = I->getAttr<UuidAttr>()) | 
| Francois Pichet | 6915c52 | 2010-12-27 01:32:00 +0000 | [diff] [blame] | 400 |       return Uuid; | 
| Francois Pichet | 6915c52 | 2010-12-27 01:32:00 +0000 | [diff] [blame] | 401 |   } | 
| Francois Pichet | 8db75a2 | 2011-05-08 10:02:20 +0000 | [diff] [blame] | 402 |  | 
| Francois Pichet | 6915c52 | 2010-12-27 01:32:00 +0000 | [diff] [blame] | 403 |   return 0; | 
| Francois Pichet | 913b7bf | 2010-12-20 03:51:03 +0000 | [diff] [blame] | 404 | } | 
 | 405 |  | 
| Francois Pichet | 01b7c30 | 2010-09-08 12:20:18 +0000 | [diff] [blame] | 406 | /// \brief Build a Microsoft __uuidof expression with a type operand. | 
 | 407 | ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, | 
 | 408 |                                 SourceLocation TypeidLoc, | 
 | 409 |                                 TypeSourceInfo *Operand, | 
 | 410 |                                 SourceLocation RParenLoc) { | 
| Francois Pichet | 6915c52 | 2010-12-27 01:32:00 +0000 | [diff] [blame] | 411 |   if (!Operand->getType()->isDependentType()) { | 
 | 412 |     if (!GetUuidAttrOfType(Operand->getType())) | 
 | 413 |       return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); | 
 | 414 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 415 |  | 
| Francois Pichet | 01b7c30 | 2010-09-08 12:20:18 +0000 | [diff] [blame] | 416 |   // FIXME: add __uuidof semantic analysis for type operand. | 
 | 417 |   return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(), | 
 | 418 |                                            Operand, | 
 | 419 |                                            SourceRange(TypeidLoc, RParenLoc))); | 
 | 420 | } | 
 | 421 |  | 
 | 422 | /// \brief Build a Microsoft __uuidof expression with an expression operand. | 
 | 423 | ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, | 
 | 424 |                                 SourceLocation TypeidLoc, | 
 | 425 |                                 Expr *E, | 
 | 426 |                                 SourceLocation RParenLoc) { | 
| Francois Pichet | 6915c52 | 2010-12-27 01:32:00 +0000 | [diff] [blame] | 427 |   if (!E->getType()->isDependentType()) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 428 |     if (!GetUuidAttrOfType(E->getType()) && | 
| Francois Pichet | 6915c52 | 2010-12-27 01:32:00 +0000 | [diff] [blame] | 429 |         !E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) | 
 | 430 |       return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); | 
 | 431 |   } | 
 | 432 |   // FIXME: add __uuidof semantic analysis for type operand. | 
| Francois Pichet | 01b7c30 | 2010-09-08 12:20:18 +0000 | [diff] [blame] | 433 |   return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(), | 
 | 434 |                                            E, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 435 |                                            SourceRange(TypeidLoc, RParenLoc))); | 
| Francois Pichet | 01b7c30 | 2010-09-08 12:20:18 +0000 | [diff] [blame] | 436 | } | 
 | 437 |  | 
 | 438 | /// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression); | 
 | 439 | ExprResult | 
 | 440 | Sema::ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc, | 
 | 441 |                      bool isType, void *TyOrExpr, SourceLocation RParenLoc) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 442 |   // If MSVCGuidDecl has not been cached, do the lookup. | 
| Francois Pichet | 01b7c30 | 2010-09-08 12:20:18 +0000 | [diff] [blame] | 443 |   if (!MSVCGuidDecl) { | 
 | 444 |     IdentifierInfo *GuidII = &PP.getIdentifierTable().get("_GUID"); | 
 | 445 |     LookupResult R(*this, GuidII, SourceLocation(), LookupTagName); | 
 | 446 |     LookupQualifiedName(R, Context.getTranslationUnitDecl()); | 
 | 447 |     MSVCGuidDecl = R.getAsSingle<RecordDecl>(); | 
 | 448 |     if (!MSVCGuidDecl) | 
 | 449 |       return ExprError(Diag(OpLoc, diag::err_need_header_before_ms_uuidof)); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 450 |   } | 
 | 451 |  | 
| Francois Pichet | 01b7c30 | 2010-09-08 12:20:18 +0000 | [diff] [blame] | 452 |   QualType GuidType = Context.getTypeDeclType(MSVCGuidDecl); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 453 |  | 
| Francois Pichet | 01b7c30 | 2010-09-08 12:20:18 +0000 | [diff] [blame] | 454 |   if (isType) { | 
 | 455 |     // The operand is a type; handle it as such. | 
 | 456 |     TypeSourceInfo *TInfo = 0; | 
 | 457 |     QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr), | 
 | 458 |                                    &TInfo); | 
 | 459 |     if (T.isNull()) | 
 | 460 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 461 |  | 
| Francois Pichet | 01b7c30 | 2010-09-08 12:20:18 +0000 | [diff] [blame] | 462 |     if (!TInfo) | 
 | 463 |       TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc); | 
 | 464 |  | 
 | 465 |     return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc); | 
 | 466 |   } | 
 | 467 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 468 |   // The operand is an expression. | 
| Francois Pichet | 01b7c30 | 2010-09-08 12:20:18 +0000 | [diff] [blame] | 469 |   return BuildCXXUuidof(GuidType, OpLoc, (Expr*)TyOrExpr, RParenLoc); | 
 | 470 | } | 
 | 471 |  | 
| Steve Naroff | 1b273c4 | 2007-09-16 14:56:35 +0000 | [diff] [blame] | 472 | /// ActOnCXXBoolLiteral - Parse {true,false} literals. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 473 | ExprResult | 
| Steve Naroff | 1b273c4 | 2007-09-16 14:56:35 +0000 | [diff] [blame] | 474 | Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { | 
| Douglas Gregor | 2f639b9 | 2008-10-24 15:36:09 +0000 | [diff] [blame] | 475 |   assert((Kind == tok::kw_true || Kind == tok::kw_false) && | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 476 |          "Unknown C++ Boolean value!"); | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 477 |   return Owned(new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true, | 
 | 478 |                                                 Context.BoolTy, OpLoc)); | 
| Reid Spencer | 5f016e2 | 2007-07-11 17:01:13 +0000 | [diff] [blame] | 479 | } | 
| Chris Lattner | 50dd289 | 2008-02-26 00:51:44 +0000 | [diff] [blame] | 480 |  | 
| Sebastian Redl | 6e8ed16 | 2009-05-10 18:38:11 +0000 | [diff] [blame] | 481 | /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 482 | ExprResult | 
| Sebastian Redl | 6e8ed16 | 2009-05-10 18:38:11 +0000 | [diff] [blame] | 483 | Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) { | 
 | 484 |   return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc)); | 
 | 485 | } | 
 | 486 |  | 
| Chris Lattner | 50dd289 | 2008-02-26 00:51:44 +0000 | [diff] [blame] | 487 | /// ActOnCXXThrow - Parse throw expressions. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 488 | ExprResult | 
| Douglas Gregor | bca01b4 | 2011-07-06 22:04:06 +0000 | [diff] [blame] | 489 | Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) { | 
 | 490 |   bool IsThrownVarInScope = false; | 
 | 491 |   if (Ex) { | 
 | 492 |     // C++0x [class.copymove]p31: | 
 | 493 |     //   When certain criteria are met, an implementation is allowed to omit the  | 
 | 494 |     //   copy/move construction of a class object [...] | 
 | 495 |     // | 
 | 496 |     //     - in a throw-expression, when the operand is the name of a  | 
 | 497 |     //       non-volatile automatic object (other than a function or catch- | 
 | 498 |     //       clause parameter) whose scope does not extend beyond the end of the  | 
 | 499 |     //       innermost enclosing try-block (if there is one), the copy/move  | 
 | 500 |     //       operation from the operand to the exception object (15.1) can be  | 
 | 501 |     //       omitted by constructing the automatic object directly into the  | 
 | 502 |     //       exception object | 
 | 503 |     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex->IgnoreParens())) | 
 | 504 |       if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) { | 
 | 505 |         if (Var->hasLocalStorage() && !Var->getType().isVolatileQualified()) { | 
 | 506 |           for( ; S; S = S->getParent()) { | 
 | 507 |             if (S->isDeclScope(Var)) { | 
 | 508 |               IsThrownVarInScope = true; | 
 | 509 |               break; | 
 | 510 |             } | 
 | 511 |              | 
 | 512 |             if (S->getFlags() & | 
 | 513 |                 (Scope::FnScope | Scope::ClassScope | Scope::BlockScope | | 
 | 514 |                  Scope::FunctionPrototypeScope | Scope::ObjCMethodScope | | 
 | 515 |                  Scope::TryScope)) | 
 | 516 |               break; | 
 | 517 |           } | 
 | 518 |         } | 
 | 519 |       } | 
 | 520 |   } | 
 | 521 |    | 
 | 522 |   return BuildCXXThrow(OpLoc, Ex, IsThrownVarInScope); | 
 | 523 | } | 
 | 524 |  | 
 | 525 | ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,  | 
 | 526 |                                bool IsThrownVarInScope) { | 
| Anders Carlsson | 729b853 | 2011-02-23 03:46:46 +0000 | [diff] [blame] | 527 |   // Don't report an error if 'throw' is used in system headers. | 
| Anders Carlsson | 15348ae | 2011-02-28 02:27:16 +0000 | [diff] [blame] | 528 |   if (!getLangOptions().CXXExceptions && | 
| Anders Carlsson | 729b853 | 2011-02-23 03:46:46 +0000 | [diff] [blame] | 529 |       !getSourceManager().isInSystemHeader(OpLoc)) | 
| Anders Carlsson | b1fba31 | 2011-02-19 21:53:09 +0000 | [diff] [blame] | 530 |     Diag(OpLoc, diag::err_exceptions_disabled) << "throw"; | 
| Douglas Gregor | bca01b4 | 2011-07-06 22:04:06 +0000 | [diff] [blame] | 531 |    | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 532 |   if (Ex && !Ex->isTypeDependent()) { | 
| Douglas Gregor | bca01b4 | 2011-07-06 22:04:06 +0000 | [diff] [blame] | 533 |     ExprResult ExRes = CheckCXXThrowOperand(OpLoc, Ex, IsThrownVarInScope); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 534 |     if (ExRes.isInvalid()) | 
 | 535 |       return ExprError(); | 
 | 536 |     Ex = ExRes.take(); | 
 | 537 |   } | 
| Douglas Gregor | bca01b4 | 2011-07-06 22:04:06 +0000 | [diff] [blame] | 538 |    | 
 | 539 |   return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc, | 
 | 540 |                                           IsThrownVarInScope)); | 
| Sebastian Redl | 972041f | 2009-04-27 20:27:31 +0000 | [diff] [blame] | 541 | } | 
 | 542 |  | 
 | 543 | /// CheckCXXThrowOperand - Validate the operand of a throw. | 
| Douglas Gregor | bca01b4 | 2011-07-06 22:04:06 +0000 | [diff] [blame] | 544 | ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, | 
 | 545 |                                       bool IsThrownVarInScope) { | 
| Sebastian Redl | 972041f | 2009-04-27 20:27:31 +0000 | [diff] [blame] | 546 |   // C++ [except.throw]p3: | 
| Douglas Gregor | 154fe98 | 2009-12-23 22:04:40 +0000 | [diff] [blame] | 547 |   //   A throw-expression initializes a temporary object, called the exception | 
 | 548 |   //   object, the type of which is determined by removing any top-level | 
 | 549 |   //   cv-qualifiers from the static type of the operand of throw and adjusting | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 550 |   //   the type from "array of T" or "function returning T" to "pointer to T" | 
| Douglas Gregor | 154fe98 | 2009-12-23 22:04:40 +0000 | [diff] [blame] | 551 |   //   or "pointer to function returning T", [...] | 
 | 552 |   if (E->getType().hasQualifiers()) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 553 |     E = ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp, | 
| Eli Friedman | c1c0dfb | 2011-09-27 21:58:52 +0000 | [diff] [blame] | 554 |                           E->getValueKind()).take(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 555 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 556 |   ExprResult Res = DefaultFunctionArrayConversion(E); | 
 | 557 |   if (Res.isInvalid()) | 
 | 558 |     return ExprError(); | 
 | 559 |   E = Res.take(); | 
| Sebastian Redl | 972041f | 2009-04-27 20:27:31 +0000 | [diff] [blame] | 560 |  | 
 | 561 |   //   If the type of the exception would be an incomplete type or a pointer | 
 | 562 |   //   to an incomplete type other than (cv) void the program is ill-formed. | 
 | 563 |   QualType Ty = E->getType(); | 
| John McCall | ac41816 | 2010-04-22 01:10:34 +0000 | [diff] [blame] | 564 |   bool isPointer = false; | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 565 |   if (const PointerType* Ptr = Ty->getAs<PointerType>()) { | 
| Sebastian Redl | 972041f | 2009-04-27 20:27:31 +0000 | [diff] [blame] | 566 |     Ty = Ptr->getPointeeType(); | 
| John McCall | ac41816 | 2010-04-22 01:10:34 +0000 | [diff] [blame] | 567 |     isPointer = true; | 
| Sebastian Redl | 972041f | 2009-04-27 20:27:31 +0000 | [diff] [blame] | 568 |   } | 
 | 569 |   if (!isPointer || !Ty->isVoidType()) { | 
 | 570 |     if (RequireCompleteType(ThrowLoc, Ty, | 
| Anders Carlsson | d497ba7 | 2009-08-26 22:59:12 +0000 | [diff] [blame] | 571 |                             PDiag(isPointer ? diag::err_throw_incomplete_ptr | 
 | 572 |                                             : diag::err_throw_incomplete) | 
 | 573 |                               << E->getSourceRange())) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 574 |       return ExprError(); | 
| Rafael Espindola | 7b9a5aa | 2010-03-02 21:28:26 +0000 | [diff] [blame] | 575 |  | 
| Douglas Gregor | bf422f9 | 2010-04-15 18:05:39 +0000 | [diff] [blame] | 576 |     if (RequireNonAbstractType(ThrowLoc, E->getType(), | 
 | 577 |                                PDiag(diag::err_throw_abstract_type) | 
 | 578 |                                  << E->getSourceRange())) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 579 |       return ExprError(); | 
| Sebastian Redl | 972041f | 2009-04-27 20:27:31 +0000 | [diff] [blame] | 580 |   } | 
 | 581 |  | 
| John McCall | ac41816 | 2010-04-22 01:10:34 +0000 | [diff] [blame] | 582 |   // Initialize the exception result.  This implicitly weeds out | 
 | 583 |   // abstract types or types with inaccessible copy constructors. | 
| Douglas Gregor | bca01b4 | 2011-07-06 22:04:06 +0000 | [diff] [blame] | 584 |    | 
 | 585 |   // C++0x [class.copymove]p31: | 
 | 586 |   //   When certain criteria are met, an implementation is allowed to omit the  | 
 | 587 |   //   copy/move construction of a class object [...] | 
 | 588 |   // | 
 | 589 |   //     - in a throw-expression, when the operand is the name of a  | 
 | 590 |   //       non-volatile automatic object (other than a function or catch-clause  | 
 | 591 |   //       parameter) whose scope does not extend beyond the end of the  | 
 | 592 |   //       innermost enclosing try-block (if there is one), the copy/move  | 
 | 593 |   //       operation from the operand to the exception object (15.1) can be  | 
 | 594 |   //       omitted by constructing the automatic object directly into the  | 
 | 595 |   //       exception object | 
 | 596 |   const VarDecl *NRVOVariable = 0; | 
 | 597 |   if (IsThrownVarInScope) | 
 | 598 |     NRVOVariable = getCopyElisionCandidate(QualType(), E, false); | 
 | 599 |    | 
| John McCall | ac41816 | 2010-04-22 01:10:34 +0000 | [diff] [blame] | 600 |   InitializedEntity Entity = | 
| Douglas Gregor | 72dfa27 | 2011-01-21 22:46:35 +0000 | [diff] [blame] | 601 |       InitializedEntity::InitializeException(ThrowLoc, E->getType(), | 
| Douglas Gregor | bca01b4 | 2011-07-06 22:04:06 +0000 | [diff] [blame] | 602 |                                              /*NRVO=*/NRVOVariable != 0); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 603 |   Res = PerformMoveOrCopyInitialization(Entity, NRVOVariable, | 
| Douglas Gregor | bca01b4 | 2011-07-06 22:04:06 +0000 | [diff] [blame] | 604 |                                         QualType(), E, | 
 | 605 |                                         IsThrownVarInScope); | 
| John McCall | ac41816 | 2010-04-22 01:10:34 +0000 | [diff] [blame] | 606 |   if (Res.isInvalid()) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 607 |     return ExprError(); | 
 | 608 |   E = Res.take(); | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 609 |  | 
| Eli Friedman | 5ed9b93 | 2010-06-03 20:39:03 +0000 | [diff] [blame] | 610 |   // If the exception has class type, we need additional handling. | 
 | 611 |   const RecordType *RecordTy = Ty->getAs<RecordType>(); | 
 | 612 |   if (!RecordTy) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 613 |     return Owned(E); | 
| Eli Friedman | 5ed9b93 | 2010-06-03 20:39:03 +0000 | [diff] [blame] | 614 |   CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); | 
 | 615 |  | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 616 |   // If we are throwing a polymorphic class type or pointer thereof, | 
 | 617 |   // exception handling will make use of the vtable. | 
| Eli Friedman | 5ed9b93 | 2010-06-03 20:39:03 +0000 | [diff] [blame] | 618 |   MarkVTableUsed(ThrowLoc, RD); | 
 | 619 |  | 
| Eli Friedman | 98efb9f | 2010-10-12 20:32:36 +0000 | [diff] [blame] | 620 |   // If a pointer is thrown, the referenced object will not be destroyed. | 
 | 621 |   if (isPointer) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 622 |     return Owned(E); | 
| Eli Friedman | 98efb9f | 2010-10-12 20:32:36 +0000 | [diff] [blame] | 623 |  | 
| Eli Friedman | 5ed9b93 | 2010-06-03 20:39:03 +0000 | [diff] [blame] | 624 |   // If the class has a non-trivial destructor, we must be able to call it. | 
 | 625 |   if (RD->hasTrivialDestructor()) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 626 |     return Owned(E); | 
| Eli Friedman | 5ed9b93 | 2010-06-03 20:39:03 +0000 | [diff] [blame] | 627 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 628 |   CXXDestructorDecl *Destructor | 
| Douglas Gregor | db89f28 | 2010-07-01 22:47:18 +0000 | [diff] [blame] | 629 |     = const_cast<CXXDestructorDecl*>(LookupDestructor(RD)); | 
| Eli Friedman | 5ed9b93 | 2010-06-03 20:39:03 +0000 | [diff] [blame] | 630 |   if (!Destructor) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 631 |     return Owned(E); | 
| Eli Friedman | 5ed9b93 | 2010-06-03 20:39:03 +0000 | [diff] [blame] | 632 |  | 
 | 633 |   MarkDeclarationReferenced(E->getExprLoc(), Destructor); | 
 | 634 |   CheckDestructorAccess(E->getExprLoc(), Destructor, | 
| Douglas Gregor | ed8abf1 | 2010-07-08 06:14:04 +0000 | [diff] [blame] | 635 |                         PDiag(diag::err_access_dtor_exception) << Ty); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 636 |   return Owned(E); | 
| Chris Lattner | 50dd289 | 2008-02-26 00:51:44 +0000 | [diff] [blame] | 637 | } | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 638 |  | 
| Douglas Gregor | 341350e | 2011-10-18 16:47:30 +0000 | [diff] [blame] | 639 | QualType Sema::getCurrentThisType(bool Capture) { | 
| John McCall | 5808ce4 | 2011-02-03 08:15:49 +0000 | [diff] [blame] | 640 |   // Ignore block scopes: we can capture through them. | 
 | 641 |   // Ignore nested enum scopes: we'll diagnose non-constant expressions | 
 | 642 |   // where they're invalid, and other uses are legitimate. | 
 | 643 |   // Don't ignore nested class scopes: you can't use 'this' in a local class. | 
| John McCall | 469a1eb | 2011-02-02 13:00:07 +0000 | [diff] [blame] | 644 |   DeclContext *DC = CurContext; | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 645 |   unsigned NumBlocks = 0; | 
| John McCall | 5808ce4 | 2011-02-03 08:15:49 +0000 | [diff] [blame] | 646 |   while (true) { | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 647 |     if (isa<BlockDecl>(DC)) { | 
 | 648 |       DC = cast<BlockDecl>(DC)->getDeclContext(); | 
 | 649 |       ++NumBlocks; | 
 | 650 |     } else if (isa<EnumDecl>(DC)) | 
 | 651 |       DC = cast<EnumDecl>(DC)->getDeclContext(); | 
| John McCall | 5808ce4 | 2011-02-03 08:15:49 +0000 | [diff] [blame] | 652 |     else break; | 
 | 653 |   } | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 654 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 655 |   QualType ThisTy; | 
 | 656 |   if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) { | 
 | 657 |     if (method && method->isInstance()) | 
 | 658 |       ThisTy = method->getThisType(Context); | 
 | 659 |   } else if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) { | 
 | 660 |     // C++0x [expr.prim]p4: | 
 | 661 |     //   Otherwise, if a member-declarator declares a non-static data member | 
 | 662 |     // of a class X, the expression this is a prvalue of type "pointer to X" | 
 | 663 |     // within the optional brace-or-equal-initializer. | 
 | 664 |     Scope *S = getScopeForContext(DC); | 
 | 665 |     if (!S || S->getFlags() & Scope::ThisScope) | 
 | 666 |       ThisTy = Context.getPointerType(Context.getRecordType(RD)); | 
 | 667 |   } | 
| John McCall | 469a1eb | 2011-02-02 13:00:07 +0000 | [diff] [blame] | 668 |  | 
| Douglas Gregor | 341350e | 2011-10-18 16:47:30 +0000 | [diff] [blame] | 669 |   if (!Capture || ThisTy.isNull()) | 
 | 670 |     return ThisTy; | 
 | 671 |    | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 672 |   // Mark that we're closing on 'this' in all the block scopes we ignored. | 
| Douglas Gregor | 341350e | 2011-10-18 16:47:30 +0000 | [diff] [blame] | 673 |   for (unsigned idx = FunctionScopes.size() - 1; | 
 | 674 |        NumBlocks; --idx, --NumBlocks) | 
 | 675 |     cast<BlockScopeInfo>(FunctionScopes[idx])->CapturesCXXThis = true; | 
| John McCall | 469a1eb | 2011-02-02 13:00:07 +0000 | [diff] [blame] | 676 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 677 |   return ThisTy; | 
| John McCall | 5808ce4 | 2011-02-03 08:15:49 +0000 | [diff] [blame] | 678 | } | 
 | 679 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 680 | ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { | 
| John McCall | 5808ce4 | 2011-02-03 08:15:49 +0000 | [diff] [blame] | 681 |   /// C++ 9.3.2: In the body of a non-static member function, the keyword this | 
 | 682 |   /// is a non-lvalue expression whose value is the address of the object for | 
 | 683 |   /// which the function is called. | 
 | 684 |  | 
| Douglas Gregor | 341350e | 2011-10-18 16:47:30 +0000 | [diff] [blame] | 685 |   QualType ThisTy = getCurrentThisType(); | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 686 |   if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use); | 
| John McCall | 5808ce4 | 2011-02-03 08:15:49 +0000 | [diff] [blame] | 687 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 688 |   return Owned(new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false)); | 
| Argyrios Kyrtzidis | 0795232 | 2008-07-01 10:37:29 +0000 | [diff] [blame] | 689 | } | 
| Argyrios Kyrtzidis | 987a14b | 2008-08-22 15:38:55 +0000 | [diff] [blame] | 690 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 691 | ExprResult | 
| Douglas Gregor | ab6677e | 2010-09-08 00:15:04 +0000 | [diff] [blame] | 692 | Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep, | 
| Argyrios Kyrtzidis | 987a14b | 2008-08-22 15:38:55 +0000 | [diff] [blame] | 693 |                                 SourceLocation LParenLoc, | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 694 |                                 MultiExprArg exprs, | 
| Argyrios Kyrtzidis | 987a14b | 2008-08-22 15:38:55 +0000 | [diff] [blame] | 695 |                                 SourceLocation RParenLoc) { | 
| Douglas Gregor | ae4c77d | 2010-02-05 19:11:37 +0000 | [diff] [blame] | 696 |   if (!TypeRep) | 
 | 697 |     return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 698 |  | 
| John McCall | 9d12503 | 2010-01-15 18:39:57 +0000 | [diff] [blame] | 699 |   TypeSourceInfo *TInfo; | 
 | 700 |   QualType Ty = GetTypeFromParser(TypeRep, &TInfo); | 
 | 701 |   if (!TInfo) | 
 | 702 |     TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation()); | 
| Douglas Gregor | ab6677e | 2010-09-08 00:15:04 +0000 | [diff] [blame] | 703 |  | 
 | 704 |   return BuildCXXTypeConstructExpr(TInfo, LParenLoc, exprs, RParenLoc); | 
 | 705 | } | 
 | 706 |  | 
 | 707 | /// ActOnCXXTypeConstructExpr - Parse construction of a specified type. | 
 | 708 | /// Can be interpreted either as function-style casting ("int(x)") | 
 | 709 | /// or class type construction ("ClassType(x,y,z)") | 
 | 710 | /// or creation of a value-initialized type ("int()"). | 
 | 711 | ExprResult | 
 | 712 | Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, | 
 | 713 |                                 SourceLocation LParenLoc, | 
 | 714 |                                 MultiExprArg exprs, | 
 | 715 |                                 SourceLocation RParenLoc) { | 
 | 716 |   QualType Ty = TInfo->getType(); | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 717 |   unsigned NumExprs = exprs.size(); | 
 | 718 |   Expr **Exprs = (Expr**)exprs.get(); | 
| Douglas Gregor | ab6677e | 2010-09-08 00:15:04 +0000 | [diff] [blame] | 719 |   SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc(); | 
| Argyrios Kyrtzidis | 987a14b | 2008-08-22 15:38:55 +0000 | [diff] [blame] | 720 |   SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc); | 
 | 721 |  | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 722 |   if (Ty->isDependentType() || | 
| Douglas Gregor | ba49817 | 2009-03-13 21:01:28 +0000 | [diff] [blame] | 723 |       CallExpr::hasAnyTypeDependentArguments(Exprs, NumExprs)) { | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 724 |     exprs.release(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 725 |  | 
| Douglas Gregor | ab6677e | 2010-09-08 00:15:04 +0000 | [diff] [blame] | 726 |     return Owned(CXXUnresolvedConstructExpr::Create(Context, TInfo, | 
| Douglas Gregor | d81e6ca | 2009-05-20 18:46:25 +0000 | [diff] [blame] | 727 |                                                     LParenLoc, | 
 | 728 |                                                     Exprs, NumExprs, | 
 | 729 |                                                     RParenLoc)); | 
| Douglas Gregor | ba49817 | 2009-03-13 21:01:28 +0000 | [diff] [blame] | 730 |   } | 
 | 731 |  | 
| Anders Carlsson | bb60a50 | 2009-08-27 03:53:50 +0000 | [diff] [blame] | 732 |   if (Ty->isArrayType()) | 
 | 733 |     return ExprError(Diag(TyBeginLoc, | 
 | 734 |                           diag::err_value_init_for_array_type) << FullRange); | 
 | 735 |   if (!Ty->isVoidType() && | 
 | 736 |       RequireCompleteType(TyBeginLoc, Ty, | 
 | 737 |                           PDiag(diag::err_invalid_incomplete_type_use) | 
 | 738 |                             << FullRange)) | 
 | 739 |     return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 740 |  | 
| Anders Carlsson | bb60a50 | 2009-08-27 03:53:50 +0000 | [diff] [blame] | 741 |   if (RequireNonAbstractType(TyBeginLoc, Ty, | 
 | 742 |                              diag::err_allocation_of_abstract_type)) | 
 | 743 |     return ExprError(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 744 |  | 
 | 745 |  | 
| Douglas Gregor | 506ae41 | 2009-01-16 18:33:17 +0000 | [diff] [blame] | 746 |   // C++ [expr.type.conv]p1: | 
| Argyrios Kyrtzidis | 987a14b | 2008-08-22 15:38:55 +0000 | [diff] [blame] | 747 |   // If the expression list is a single expression, the type conversion | 
 | 748 |   // expression is equivalent (in definedness, and if defined in meaning) to the | 
 | 749 |   // corresponding cast expression. | 
| Argyrios Kyrtzidis | 987a14b | 2008-08-22 15:38:55 +0000 | [diff] [blame] | 750 |   if (NumExprs == 1) { | 
| John McCall | b45ae25 | 2011-10-05 07:41:44 +0000 | [diff] [blame] | 751 |     Expr *Arg = Exprs[0]; | 
| Anders Carlsson | 0aebc81 | 2009-09-09 21:33:21 +0000 | [diff] [blame] | 752 |     exprs.release(); | 
| John McCall | b45ae25 | 2011-10-05 07:41:44 +0000 | [diff] [blame] | 753 |     return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc); | 
| Argyrios Kyrtzidis | 987a14b | 2008-08-22 15:38:55 +0000 | [diff] [blame] | 754 |   } | 
 | 755 |  | 
| Douglas Gregor | 19311e7 | 2010-09-08 21:40:08 +0000 | [diff] [blame] | 756 |   InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); | 
 | 757 |   InitializationKind Kind | 
 | 758 |     = NumExprs ? InitializationKind::CreateDirect(TyBeginLoc, | 
 | 759 |                                                   LParenLoc, RParenLoc) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 760 |                : InitializationKind::CreateValue(TyBeginLoc, | 
| Douglas Gregor | 19311e7 | 2010-09-08 21:40:08 +0000 | [diff] [blame] | 761 |                                                  LParenLoc, RParenLoc); | 
 | 762 |   InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs); | 
 | 763 |   ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(exprs)); | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 764 |  | 
| Douglas Gregor | 19311e7 | 2010-09-08 21:40:08 +0000 | [diff] [blame] | 765 |   // FIXME: Improve AST representation? | 
 | 766 |   return move(Result); | 
| Argyrios Kyrtzidis | 987a14b | 2008-08-22 15:38:55 +0000 | [diff] [blame] | 767 | } | 
| Argyrios Kyrtzidis | 5921093 | 2008-09-10 02:17:11 +0000 | [diff] [blame] | 768 |  | 
| John McCall | 6ec278d | 2011-01-27 09:37:56 +0000 | [diff] [blame] | 769 | /// doesUsualArrayDeleteWantSize - Answers whether the usual | 
 | 770 | /// operator delete[] for the given type has a size_t parameter. | 
 | 771 | static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc, | 
 | 772 |                                          QualType allocType) { | 
 | 773 |   const RecordType *record = | 
 | 774 |     allocType->getBaseElementTypeUnsafe()->getAs<RecordType>(); | 
 | 775 |   if (!record) return false; | 
 | 776 |  | 
 | 777 |   // Try to find an operator delete[] in class scope. | 
 | 778 |  | 
 | 779 |   DeclarationName deleteName = | 
 | 780 |     S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete); | 
 | 781 |   LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName); | 
 | 782 |   S.LookupQualifiedName(ops, record->getDecl()); | 
 | 783 |  | 
 | 784 |   // We're just doing this for information. | 
 | 785 |   ops.suppressDiagnostics(); | 
 | 786 |  | 
 | 787 |   // Very likely: there's no operator delete[]. | 
 | 788 |   if (ops.empty()) return false; | 
 | 789 |  | 
 | 790 |   // If it's ambiguous, it should be illegal to call operator delete[] | 
 | 791 |   // on this thing, so it doesn't matter if we allocate extra space or not. | 
 | 792 |   if (ops.isAmbiguous()) return false; | 
 | 793 |  | 
 | 794 |   LookupResult::Filter filter = ops.makeFilter(); | 
 | 795 |   while (filter.hasNext()) { | 
 | 796 |     NamedDecl *del = filter.next()->getUnderlyingDecl(); | 
 | 797 |  | 
 | 798 |     // C++0x [basic.stc.dynamic.deallocation]p2: | 
 | 799 |     //   A template instance is never a usual deallocation function, | 
 | 800 |     //   regardless of its signature. | 
 | 801 |     if (isa<FunctionTemplateDecl>(del)) { | 
 | 802 |       filter.erase(); | 
 | 803 |       continue; | 
 | 804 |     } | 
 | 805 |  | 
 | 806 |     // C++0x [basic.stc.dynamic.deallocation]p2: | 
 | 807 |     //   If class T does not declare [an operator delete[] with one | 
 | 808 |     //   parameter] but does declare a member deallocation function | 
 | 809 |     //   named operator delete[] with exactly two parameters, the | 
 | 810 |     //   second of which has type std::size_t, then this function | 
 | 811 |     //   is a usual deallocation function. | 
 | 812 |     if (!cast<CXXMethodDecl>(del)->isUsualDeallocationFunction()) { | 
 | 813 |       filter.erase(); | 
 | 814 |       continue; | 
 | 815 |     } | 
 | 816 |   } | 
 | 817 |   filter.done(); | 
 | 818 |  | 
 | 819 |   if (!ops.isSingleResult()) return false; | 
 | 820 |  | 
 | 821 |   const FunctionDecl *del = cast<FunctionDecl>(ops.getFoundDecl()); | 
 | 822 |   return (del->getNumParams() == 2); | 
 | 823 | } | 
| Argyrios Kyrtzidis | 5921093 | 2008-09-10 02:17:11 +0000 | [diff] [blame] | 824 |  | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 825 | /// ActOnCXXNew - Parsed a C++ 'new' expression (C++ 5.3.4), as in e.g.: | 
 | 826 | /// @code new (memory) int[size][4] @endcode | 
 | 827 | /// or | 
 | 828 | /// @code ::new Foo(23, "hello") @endcode | 
 | 829 | /// For the interpretation of this heap of arguments, consult the base version. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 830 | ExprResult | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 831 | Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 832 |                   SourceLocation PlacementLParen, MultiExprArg PlacementArgs, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 833 |                   SourceLocation PlacementRParen, SourceRange TypeIdParens, | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 834 |                   Declarator &D, SourceLocation ConstructorLParen, | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 835 |                   MultiExprArg ConstructorArgs, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 836 |                   SourceLocation ConstructorRParen) { | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 837 |   bool TypeContainsAuto = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto; | 
 | 838 |  | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 839 |   Expr *ArraySize = 0; | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 840 |   // If the specified type is an array, unwrap it and save the expression. | 
 | 841 |   if (D.getNumTypeObjects() > 0 && | 
 | 842 |       D.getTypeObject(0).Kind == DeclaratorChunk::Array) { | 
 | 843 |     DeclaratorChunk &Chunk = D.getTypeObject(0); | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 844 |     if (TypeContainsAuto) | 
 | 845 |       return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto) | 
 | 846 |         << D.getSourceRange()); | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 847 |     if (Chunk.Arr.hasStatic) | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 848 |       return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new) | 
 | 849 |         << D.getSourceRange()); | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 850 |     if (!Chunk.Arr.NumElts) | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 851 |       return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size) | 
 | 852 |         << D.getSourceRange()); | 
| Sebastian Redl | 8ce35b0 | 2009-10-25 21:45:37 +0000 | [diff] [blame] | 853 |  | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 854 |     ArraySize = static_cast<Expr*>(Chunk.Arr.NumElts); | 
| Sebastian Redl | 8ce35b0 | 2009-10-25 21:45:37 +0000 | [diff] [blame] | 855 |     D.DropFirstTypeObject(); | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 856 |   } | 
 | 857 |  | 
| Douglas Gregor | 043cad2 | 2009-09-11 00:18:58 +0000 | [diff] [blame] | 858 |   // Every dimension shall be of constant size. | 
| Sebastian Redl | 8ce35b0 | 2009-10-25 21:45:37 +0000 | [diff] [blame] | 859 |   if (ArraySize) { | 
 | 860 |     for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) { | 
| Douglas Gregor | 043cad2 | 2009-09-11 00:18:58 +0000 | [diff] [blame] | 861 |       if (D.getTypeObject(I).Kind != DeclaratorChunk::Array) | 
 | 862 |         break; | 
 | 863 |  | 
 | 864 |       DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr; | 
 | 865 |       if (Expr *NumElts = (Expr *)Array.NumElts) { | 
 | 866 |         if (!NumElts->isTypeDependent() && !NumElts->isValueDependent() && | 
 | 867 |             !NumElts->isIntegerConstantExpr(Context)) { | 
 | 868 |           Diag(D.getTypeObject(I).Loc, diag::err_new_array_nonconst) | 
 | 869 |             << NumElts->getSourceRange(); | 
 | 870 |           return ExprError(); | 
 | 871 |         } | 
 | 872 |       } | 
 | 873 |     } | 
 | 874 |   } | 
| Sebastian Redl | 8ce35b0 | 2009-10-25 21:45:37 +0000 | [diff] [blame] | 875 |  | 
| Argyrios Kyrtzidis | 0b8c98f | 2011-06-28 03:01:23 +0000 | [diff] [blame] | 876 |   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/0); | 
| John McCall | bf1a028 | 2010-06-04 23:28:52 +0000 | [diff] [blame] | 877 |   QualType AllocType = TInfo->getType(); | 
| Chris Lattner | eaaebc7 | 2009-04-25 08:06:05 +0000 | [diff] [blame] | 878 |   if (D.isInvalidType()) | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 879 |     return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 880 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 881 |   return BuildCXXNew(StartLoc, UseGlobal, | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 882 |                      PlacementLParen, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 883 |                      move(PlacementArgs), | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 884 |                      PlacementRParen, | 
| Douglas Gregor | 4bd4031 | 2010-07-13 15:54:32 +0000 | [diff] [blame] | 885 |                      TypeIdParens, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 886 |                      AllocType, | 
| Douglas Gregor | 1bb2a93 | 2010-09-07 21:49:58 +0000 | [diff] [blame] | 887 |                      TInfo, | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 888 |                      ArraySize, | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 889 |                      ConstructorLParen, | 
 | 890 |                      move(ConstructorArgs), | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 891 |                      ConstructorRParen, | 
 | 892 |                      TypeContainsAuto); | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 893 | } | 
 | 894 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 895 | ExprResult | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 896 | Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, | 
 | 897 |                   SourceLocation PlacementLParen, | 
 | 898 |                   MultiExprArg PlacementArgs, | 
 | 899 |                   SourceLocation PlacementRParen, | 
| Douglas Gregor | 4bd4031 | 2010-07-13 15:54:32 +0000 | [diff] [blame] | 900 |                   SourceRange TypeIdParens, | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 901 |                   QualType AllocType, | 
| Douglas Gregor | 1bb2a93 | 2010-09-07 21:49:58 +0000 | [diff] [blame] | 902 |                   TypeSourceInfo *AllocTypeInfo, | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 903 |                   Expr *ArraySize, | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 904 |                   SourceLocation ConstructorLParen, | 
 | 905 |                   MultiExprArg ConstructorArgs, | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 906 |                   SourceLocation ConstructorRParen, | 
 | 907 |                   bool TypeMayContainAuto) { | 
| Douglas Gregor | 1bb2a93 | 2010-09-07 21:49:58 +0000 | [diff] [blame] | 908 |   SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange(); | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 909 |  | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 910 |   // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. | 
 | 911 |   if (TypeMayContainAuto && AllocType->getContainedAutoType()) { | 
 | 912 |     if (ConstructorArgs.size() == 0) | 
 | 913 |       return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg) | 
 | 914 |                        << AllocType << TypeRange); | 
 | 915 |     if (ConstructorArgs.size() != 1) { | 
 | 916 |       Expr *FirstBad = ConstructorArgs.get()[1]; | 
 | 917 |       return ExprError(Diag(FirstBad->getSourceRange().getBegin(), | 
 | 918 |                             diag::err_auto_new_ctor_multiple_expressions) | 
 | 919 |                        << AllocType << TypeRange); | 
 | 920 |     } | 
| Richard Smith | a085da8 | 2011-03-17 16:11:59 +0000 | [diff] [blame] | 921 |     TypeSourceInfo *DeducedType = 0; | 
 | 922 |     if (!DeduceAutoType(AllocTypeInfo, ConstructorArgs.get()[0], DeducedType)) | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 923 |       return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure) | 
 | 924 |                        << AllocType | 
 | 925 |                        << ConstructorArgs.get()[0]->getType() | 
 | 926 |                        << TypeRange | 
 | 927 |                        << ConstructorArgs.get()[0]->getSourceRange()); | 
| Richard Smith | a085da8 | 2011-03-17 16:11:59 +0000 | [diff] [blame] | 928 |     if (!DeducedType) | 
 | 929 |       return ExprError(); | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 930 |  | 
| Richard Smith | a085da8 | 2011-03-17 16:11:59 +0000 | [diff] [blame] | 931 |     AllocTypeInfo = DeducedType; | 
 | 932 |     AllocType = AllocTypeInfo->getType(); | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 933 |   } | 
 | 934 |    | 
| Douglas Gregor | 3caf04e | 2010-05-16 16:01:03 +0000 | [diff] [blame] | 935 |   // Per C++0x [expr.new]p5, the type being constructed may be a | 
 | 936 |   // typedef of an array type. | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 937 |   if (!ArraySize) { | 
| Douglas Gregor | 3caf04e | 2010-05-16 16:01:03 +0000 | [diff] [blame] | 938 |     if (const ConstantArrayType *Array | 
 | 939 |                               = Context.getAsConstantArrayType(AllocType)) { | 
| Argyrios Kyrtzidis | 9996a7f | 2010-08-28 09:06:06 +0000 | [diff] [blame] | 940 |       ArraySize = IntegerLiteral::Create(Context, Array->getSize(), | 
 | 941 |                                          Context.getSizeType(), | 
 | 942 |                                          TypeRange.getEnd()); | 
| Douglas Gregor | 3caf04e | 2010-05-16 16:01:03 +0000 | [diff] [blame] | 943 |       AllocType = Array->getElementType(); | 
 | 944 |     } | 
 | 945 |   } | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 946 |  | 
| Douglas Gregor | a075076 | 2010-10-06 16:00:31 +0000 | [diff] [blame] | 947 |   if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange)) | 
 | 948 |     return ExprError(); | 
 | 949 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 950 |   // In ARC, infer 'retaining' for the allocated  | 
 | 951 |   if (getLangOptions().ObjCAutoRefCount && | 
 | 952 |       AllocType.getObjCLifetime() == Qualifiers::OCL_None && | 
 | 953 |       AllocType->isObjCLifetimeType()) { | 
 | 954 |     AllocType = Context.getLifetimeQualifiedType(AllocType, | 
 | 955 |                                     AllocType->getObjCARCImplicitLifetime()); | 
 | 956 |   } | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 957 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 958 |   QualType ResultType = Context.getPointerType(AllocType); | 
 | 959 |      | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 960 |   // C++ 5.3.4p6: "The expression in a direct-new-declarator shall have integral | 
 | 961 |   //   or enumeration type with a non-negative value." | 
| Sebastian Redl | 2850784 | 2009-02-26 14:39:58 +0000 | [diff] [blame] | 962 |   if (ArraySize && !ArraySize->isTypeDependent()) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 963 |  | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 964 |     QualType SizeType = ArraySize->getType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 965 |  | 
| Richard Smith | ebaf0e6 | 2011-10-18 20:49:44 +0000 | [diff] [blame] | 966 |     ExprResult ConvertedSize = ConvertToIntegralOrEnumerationType( | 
 | 967 |       StartLoc, ArraySize, | 
 | 968 |       PDiag(diag::err_array_size_not_integral), | 
 | 969 |       PDiag(diag::err_array_size_incomplete_type) | 
 | 970 |         << ArraySize->getSourceRange(), | 
 | 971 |       PDiag(diag::err_array_size_explicit_conversion), | 
 | 972 |       PDiag(diag::note_array_size_conversion), | 
 | 973 |       PDiag(diag::err_array_size_ambiguous_conversion), | 
 | 974 |       PDiag(diag::note_array_size_conversion), | 
 | 975 |       PDiag(getLangOptions().CPlusPlus0x ? | 
 | 976 |               diag::warn_cxx98_compat_array_size_conversion : | 
 | 977 |               diag::ext_array_size_conversion)); | 
| Douglas Gregor | 6bc574d | 2010-06-30 00:20:43 +0000 | [diff] [blame] | 978 |     if (ConvertedSize.isInvalid()) | 
 | 979 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 980 |  | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 981 |     ArraySize = ConvertedSize.take(); | 
| Douglas Gregor | 6bc574d | 2010-06-30 00:20:43 +0000 | [diff] [blame] | 982 |     SizeType = ArraySize->getType(); | 
| Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 983 |     if (!SizeType->isIntegralOrUnscopedEnumerationType()) | 
| Douglas Gregor | 6bc574d | 2010-06-30 00:20:43 +0000 | [diff] [blame] | 984 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 985 |  | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 986 |     // Let's see if this is a constant < 0. If so, we reject it out of hand. | 
 | 987 |     // We don't care about special rules, so we tell the machinery it's not | 
 | 988 |     // evaluated - it gives us a result in more cases. | 
| Sebastian Redl | 2850784 | 2009-02-26 14:39:58 +0000 | [diff] [blame] | 989 |     if (!ArraySize->isValueDependent()) { | 
 | 990 |       llvm::APSInt Value; | 
 | 991 |       if (ArraySize->isIntegerConstantExpr(Value, Context, 0, false)) { | 
 | 992 |         if (Value < llvm::APSInt( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 993 |                         llvm::APInt::getNullValue(Value.getBitWidth()), | 
| Anders Carlsson | ac18b2e | 2009-09-23 00:37:25 +0000 | [diff] [blame] | 994 |                                  Value.isUnsigned())) | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 995 |           return ExprError(Diag(ArraySize->getSourceRange().getBegin(), | 
| Douglas Gregor | 2767ce2 | 2010-08-18 00:39:00 +0000 | [diff] [blame] | 996 |                                 diag::err_typecheck_negative_array_size) | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 997 |             << ArraySize->getSourceRange()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 998 |  | 
| Douglas Gregor | 2767ce2 | 2010-08-18 00:39:00 +0000 | [diff] [blame] | 999 |         if (!AllocType->isDependentType()) { | 
 | 1000 |           unsigned ActiveSizeBits | 
 | 1001 |             = ConstantArrayType::getNumAddressingBits(Context, AllocType, Value); | 
 | 1002 |           if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1003 |             Diag(ArraySize->getSourceRange().getBegin(), | 
| Douglas Gregor | 2767ce2 | 2010-08-18 00:39:00 +0000 | [diff] [blame] | 1004 |                  diag::err_array_too_large) | 
 | 1005 |               << Value.toString(10) | 
 | 1006 |               << ArraySize->getSourceRange(); | 
 | 1007 |             return ExprError(); | 
 | 1008 |           } | 
 | 1009 |         } | 
| Douglas Gregor | 4bd4031 | 2010-07-13 15:54:32 +0000 | [diff] [blame] | 1010 |       } else if (TypeIdParens.isValid()) { | 
 | 1011 |         // Can't have dynamic array size when the type-id is in parentheses. | 
 | 1012 |         Diag(ArraySize->getLocStart(), diag::ext_new_paren_array_nonconst) | 
 | 1013 |           << ArraySize->getSourceRange() | 
 | 1014 |           << FixItHint::CreateRemoval(TypeIdParens.getBegin()) | 
 | 1015 |           << FixItHint::CreateRemoval(TypeIdParens.getEnd()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1016 |  | 
| Douglas Gregor | 4bd4031 | 2010-07-13 15:54:32 +0000 | [diff] [blame] | 1017 |         TypeIdParens = SourceRange(); | 
| Sebastian Redl | 2850784 | 2009-02-26 14:39:58 +0000 | [diff] [blame] | 1018 |       } | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 1019 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1020 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 1021 |     // ARC: warn about ABI issues. | 
 | 1022 |     if (getLangOptions().ObjCAutoRefCount) { | 
 | 1023 |       QualType BaseAllocType = Context.getBaseElementType(AllocType); | 
 | 1024 |       if (BaseAllocType.hasStrongOrWeakObjCLifetime()) | 
 | 1025 |         Diag(StartLoc, diag::warn_err_new_delete_object_array) | 
 | 1026 |           << 0 << BaseAllocType; | 
 | 1027 |     } | 
 | 1028 |  | 
| John McCall | 7d16627 | 2011-05-15 07:14:44 +0000 | [diff] [blame] | 1029 |     // Note that we do *not* convert the argument in any way.  It can | 
 | 1030 |     // be signed, larger than size_t, whatever. | 
| Sebastian Redl | cee63fb | 2008-12-02 14:43:59 +0000 | [diff] [blame] | 1031 |   } | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1032 |  | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1033 |   FunctionDecl *OperatorNew = 0; | 
 | 1034 |   FunctionDecl *OperatorDelete = 0; | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 1035 |   Expr **PlaceArgs = (Expr**)PlacementArgs.get(); | 
 | 1036 |   unsigned NumPlaceArgs = PlacementArgs.size(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1037 |  | 
| Sebastian Redl | 2850784 | 2009-02-26 14:39:58 +0000 | [diff] [blame] | 1038 |   if (!AllocType->isDependentType() && | 
 | 1039 |       !Expr::hasAnyTypeDependentArguments(PlaceArgs, NumPlaceArgs) && | 
 | 1040 |       FindAllocationFunctions(StartLoc, | 
| Sebastian Redl | 00e68e2 | 2009-02-09 18:24:27 +0000 | [diff] [blame] | 1041 |                               SourceRange(PlacementLParen, PlacementRParen), | 
 | 1042 |                               UseGlobal, AllocType, ArraySize, PlaceArgs, | 
 | 1043 |                               NumPlaceArgs, OperatorNew, OperatorDelete)) | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 1044 |     return ExprError(); | 
| John McCall | 6ec278d | 2011-01-27 09:37:56 +0000 | [diff] [blame] | 1045 |  | 
 | 1046 |   // If this is an array allocation, compute whether the usual array | 
 | 1047 |   // deallocation function for the type has a size_t parameter. | 
 | 1048 |   bool UsualArrayDeleteWantsSize = false; | 
 | 1049 |   if (ArraySize && !AllocType->isDependentType()) | 
 | 1050 |     UsualArrayDeleteWantsSize | 
 | 1051 |       = doesUsualArrayDeleteWantSize(*this, StartLoc, AllocType); | 
 | 1052 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1053 |   SmallVector<Expr *, 8> AllPlaceArgs; | 
| Fariborz Jahanian | 498429f | 2009-11-19 18:39:40 +0000 | [diff] [blame] | 1054 |   if (OperatorNew) { | 
 | 1055 |     // Add default arguments, if any. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1056 |     const FunctionProtoType *Proto = | 
| Fariborz Jahanian | 498429f | 2009-11-19 18:39:40 +0000 | [diff] [blame] | 1057 |       OperatorNew->getType()->getAs<FunctionProtoType>(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1058 |     VariadicCallType CallType = | 
| Fariborz Jahanian | 4cd1c70 | 2009-11-24 19:27:49 +0000 | [diff] [blame] | 1059 |       Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1060 |  | 
| Anders Carlsson | 28e9483 | 2010-05-03 02:07:56 +0000 | [diff] [blame] | 1061 |     if (GatherArgumentsForCall(PlacementLParen, OperatorNew, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1062 |                                Proto, 1, PlaceArgs, NumPlaceArgs, | 
| Anders Carlsson | 28e9483 | 2010-05-03 02:07:56 +0000 | [diff] [blame] | 1063 |                                AllPlaceArgs, CallType)) | 
| Fariborz Jahanian | 048f52a | 2009-11-24 18:29:37 +0000 | [diff] [blame] | 1064 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1065 |  | 
| Fariborz Jahanian | 498429f | 2009-11-19 18:39:40 +0000 | [diff] [blame] | 1066 |     NumPlaceArgs = AllPlaceArgs.size(); | 
 | 1067 |     if (NumPlaceArgs > 0) | 
 | 1068 |       PlaceArgs = &AllPlaceArgs[0]; | 
 | 1069 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1070 |  | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1071 |   bool Init = ConstructorLParen.isValid(); | 
 | 1072 |   // --- Choosing a constructor --- | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1073 |   CXXConstructorDecl *Constructor = 0; | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 1074 |   bool HadMultipleCandidates = false; | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 1075 |   Expr **ConsArgs = (Expr**)ConstructorArgs.get(); | 
 | 1076 |   unsigned NumConsArgs = ConstructorArgs.size(); | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 1077 |   ASTOwningVector<Expr*> ConvertedConstructorArgs(*this); | 
| Eli Friedman | a8ce9ec | 2009-11-08 22:15:39 +0000 | [diff] [blame] | 1078 |  | 
| Anders Carlsson | 48c9501 | 2010-05-03 15:45:23 +0000 | [diff] [blame] | 1079 |   // Array 'new' can't have any initializers. | 
| Anders Carlsson | 55cbd6e | 2010-05-16 16:24:20 +0000 | [diff] [blame] | 1080 |   if (NumConsArgs && (ResultType->isArrayType() || ArraySize)) { | 
| Anders Carlsson | 48c9501 | 2010-05-03 15:45:23 +0000 | [diff] [blame] | 1081 |     SourceRange InitRange(ConsArgs[0]->getLocStart(), | 
 | 1082 |                           ConsArgs[NumConsArgs - 1]->getLocEnd()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1083 |  | 
| Anders Carlsson | 48c9501 | 2010-05-03 15:45:23 +0000 | [diff] [blame] | 1084 |     Diag(StartLoc, diag::err_new_array_init_args) << InitRange; | 
 | 1085 |     return ExprError(); | 
 | 1086 |   } | 
 | 1087 |  | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1088 |   if (!AllocType->isDependentType() && | 
 | 1089 |       !Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) { | 
 | 1090 |     // C++0x [expr.new]p15: | 
 | 1091 |     //   A new-expression that creates an object of type T initializes that | 
 | 1092 |     //   object as follows: | 
 | 1093 |     InitializationKind Kind | 
 | 1094 |     //     - If the new-initializer is omitted, the object is default- | 
 | 1095 |     //       initialized (8.5); if no initialization is performed, | 
 | 1096 |     //       the object has indeterminate value | 
| Douglas Gregor | 1bb2a93 | 2010-09-07 21:49:58 +0000 | [diff] [blame] | 1097 |       = !Init? InitializationKind::CreateDefault(TypeRange.getBegin()) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1098 |     //     - Otherwise, the new-initializer is interpreted according to the | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1099 |     //       initialization rules of 8.5 for direct-initialization. | 
| Douglas Gregor | 1bb2a93 | 2010-09-07 21:49:58 +0000 | [diff] [blame] | 1100 |              : InitializationKind::CreateDirect(TypeRange.getBegin(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1101 |                                                 ConstructorLParen, | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1102 |                                                 ConstructorRParen); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1103 |  | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1104 |     InitializedEntity Entity | 
| Douglas Gregor | d6542d8 | 2009-12-22 15:35:07 +0000 | [diff] [blame] | 1105 |       = InitializedEntity::InitializeNew(StartLoc, AllocType); | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1106 |     InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1107 |     ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1108 |                                                 move(ConstructorArgs)); | 
 | 1109 |     if (FullInit.isInvalid()) | 
 | 1110 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1111 |  | 
 | 1112 |     // FullInit is our initializer; walk through it to determine if it's a | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1113 |     // constructor call, which CXXNewExpr handles directly. | 
 | 1114 |     if (Expr *FullInitExpr = (Expr *)FullInit.get()) { | 
 | 1115 |       if (CXXBindTemporaryExpr *Binder | 
 | 1116 |             = dyn_cast<CXXBindTemporaryExpr>(FullInitExpr)) | 
 | 1117 |         FullInitExpr = Binder->getSubExpr(); | 
 | 1118 |       if (CXXConstructExpr *Construct | 
 | 1119 |                     = dyn_cast<CXXConstructExpr>(FullInitExpr)) { | 
 | 1120 |         Constructor = Construct->getConstructor(); | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 1121 |         HadMultipleCandidates = Construct->hadMultipleCandidates(); | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1122 |         for (CXXConstructExpr::arg_iterator A = Construct->arg_begin(), | 
 | 1123 |                                          AEnd = Construct->arg_end(); | 
 | 1124 |              A != AEnd; ++A) | 
| John McCall | 3fa5cae | 2010-10-26 07:05:15 +0000 | [diff] [blame] | 1125 |           ConvertedConstructorArgs.push_back(*A); | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1126 |       } else { | 
 | 1127 |         // Take the converted initializer. | 
 | 1128 |         ConvertedConstructorArgs.push_back(FullInit.release()); | 
 | 1129 |       } | 
 | 1130 |     } else { | 
 | 1131 |       // No initialization required. | 
 | 1132 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1133 |  | 
| Douglas Gregor | 99a2e60 | 2009-12-16 01:38:02 +0000 | [diff] [blame] | 1134 |     // Take the converted arguments and use them for the new expression. | 
| Douglas Gregor | 39da0b8 | 2009-09-09 23:08:42 +0000 | [diff] [blame] | 1135 |     NumConsArgs = ConvertedConstructorArgs.size(); | 
 | 1136 |     ConsArgs = (Expr **)ConvertedConstructorArgs.take(); | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1137 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1138 |  | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1139 |   // Mark the new and delete operators as referenced. | 
 | 1140 |   if (OperatorNew) | 
 | 1141 |     MarkDeclarationReferenced(StartLoc, OperatorNew); | 
 | 1142 |   if (OperatorDelete) | 
 | 1143 |     MarkDeclarationReferenced(StartLoc, OperatorDelete); | 
 | 1144 |  | 
| John McCall | 84ff0fc | 2011-07-13 20:12:57 +0000 | [diff] [blame] | 1145 |   // C++0x [expr.new]p17: | 
 | 1146 |   //   If the new expression creates an array of objects of class type, | 
 | 1147 |   //   access and ambiguity control are done for the destructor. | 
 | 1148 |   if (ArraySize && Constructor) { | 
 | 1149 |     if (CXXDestructorDecl *dtor = LookupDestructor(Constructor->getParent())) { | 
 | 1150 |       MarkDeclarationReferenced(StartLoc, dtor); | 
 | 1151 |       CheckDestructorAccess(StartLoc, dtor,  | 
 | 1152 |                             PDiag(diag::err_access_dtor) | 
 | 1153 |                               << Context.getBaseElementType(AllocType)); | 
 | 1154 |     } | 
 | 1155 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1156 |  | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 1157 |   PlacementArgs.release(); | 
 | 1158 |   ConstructorArgs.release(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1159 |  | 
| Ted Kremenek | ad7fe86 | 2010-02-11 22:51:03 +0000 | [diff] [blame] | 1160 |   return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew, | 
| Douglas Gregor | 4bd4031 | 2010-07-13 15:54:32 +0000 | [diff] [blame] | 1161 |                                         PlaceArgs, NumPlaceArgs, TypeIdParens, | 
| Ted Kremenek | ad7fe86 | 2010-02-11 22:51:03 +0000 | [diff] [blame] | 1162 |                                         ArraySize, Constructor, Init, | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 1163 |                                         ConsArgs, NumConsArgs, | 
 | 1164 |                                         HadMultipleCandidates, | 
 | 1165 |                                         OperatorDelete, | 
| John McCall | 6ec278d | 2011-01-27 09:37:56 +0000 | [diff] [blame] | 1166 |                                         UsualArrayDeleteWantsSize, | 
| Douglas Gregor | 1bb2a93 | 2010-09-07 21:49:58 +0000 | [diff] [blame] | 1167 |                                         ResultType, AllocTypeInfo, | 
 | 1168 |                                         StartLoc, | 
| Ted Kremenek | ad7fe86 | 2010-02-11 22:51:03 +0000 | [diff] [blame] | 1169 |                                         Init ? ConstructorRParen : | 
| Chandler Carruth | 428edaf | 2010-10-25 08:47:36 +0000 | [diff] [blame] | 1170 |                                                TypeRange.getEnd(), | 
 | 1171 |                                         ConstructorLParen, ConstructorRParen)); | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1172 | } | 
 | 1173 |  | 
 | 1174 | /// CheckAllocatedType - Checks that a type is suitable as the allocated type | 
 | 1175 | /// in a new-expression. | 
 | 1176 | /// dimension off and stores the size expression in ArraySize. | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 1177 | bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1178 |                               SourceRange R) { | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1179 |   // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an | 
 | 1180 |   //   abstract class type or array thereof. | 
| Douglas Gregor | e7450f5 | 2009-03-24 19:52:54 +0000 | [diff] [blame] | 1181 |   if (AllocType->isFunctionType()) | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 1182 |     return Diag(Loc, diag::err_bad_new_type) | 
 | 1183 |       << AllocType << 0 << R; | 
| Douglas Gregor | e7450f5 | 2009-03-24 19:52:54 +0000 | [diff] [blame] | 1184 |   else if (AllocType->isReferenceType()) | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 1185 |     return Diag(Loc, diag::err_bad_new_type) | 
 | 1186 |       << AllocType << 1 << R; | 
| Douglas Gregor | e7450f5 | 2009-03-24 19:52:54 +0000 | [diff] [blame] | 1187 |   else if (!AllocType->isDependentType() && | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 1188 |            RequireCompleteType(Loc, AllocType, | 
| Anders Carlsson | b790661 | 2009-08-26 23:45:07 +0000 | [diff] [blame] | 1189 |                                PDiag(diag::err_new_incomplete_type) | 
 | 1190 |                                  << R)) | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1191 |     return true; | 
| Douglas Gregor | 3433cf7 | 2009-05-21 00:00:09 +0000 | [diff] [blame] | 1192 |   else if (RequireNonAbstractType(Loc, AllocType, | 
| Douglas Gregor | e7450f5 | 2009-03-24 19:52:54 +0000 | [diff] [blame] | 1193 |                                   diag::err_allocation_of_abstract_type)) | 
 | 1194 |     return true; | 
| Douglas Gregor | a075076 | 2010-10-06 16:00:31 +0000 | [diff] [blame] | 1195 |   else if (AllocType->isVariablyModifiedType()) | 
 | 1196 |     return Diag(Loc, diag::err_variably_modified_new_type) | 
 | 1197 |              << AllocType; | 
| Douglas Gregor | 5666d36 | 2011-04-15 19:46:20 +0000 | [diff] [blame] | 1198 |   else if (unsigned AddressSpace = AllocType.getAddressSpace()) | 
 | 1199 |     return Diag(Loc, diag::err_address_space_qualified_new) | 
 | 1200 |       << AllocType.getUnqualifiedType() << AddressSpace; | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 1201 |   else if (getLangOptions().ObjCAutoRefCount) { | 
 | 1202 |     if (const ArrayType *AT = Context.getAsArrayType(AllocType)) { | 
 | 1203 |       QualType BaseAllocType = Context.getBaseElementType(AT); | 
 | 1204 |       if (BaseAllocType.getObjCLifetime() == Qualifiers::OCL_None && | 
 | 1205 |           BaseAllocType->isObjCLifetimeType()) | 
| Argyrios Kyrtzidis | b8b0313 | 2011-06-24 00:08:59 +0000 | [diff] [blame] | 1206 |         return Diag(Loc, diag::err_arc_new_array_without_ownership) | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 1207 |           << BaseAllocType; | 
 | 1208 |     } | 
 | 1209 |   } | 
| Douglas Gregor | 5666d36 | 2011-04-15 19:46:20 +0000 | [diff] [blame] | 1210 |             | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1211 |   return false; | 
 | 1212 | } | 
 | 1213 |  | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1214 | /// \brief Determine whether the given function is a non-placement | 
 | 1215 | /// deallocation function. | 
 | 1216 | static bool isNonPlacementDeallocationFunction(FunctionDecl *FD) { | 
 | 1217 |   if (FD->isInvalidDecl()) | 
 | 1218 |     return false; | 
 | 1219 |  | 
 | 1220 |   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD)) | 
 | 1221 |     return Method->isUsualDeallocationFunction(); | 
 | 1222 |  | 
 | 1223 |   return ((FD->getOverloadedOperator() == OO_Delete || | 
 | 1224 |            FD->getOverloadedOperator() == OO_Array_Delete) && | 
 | 1225 |           FD->getNumParams() == 1); | 
 | 1226 | } | 
 | 1227 |  | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1228 | /// FindAllocationFunctions - Finds the overloads of operator new and delete | 
 | 1229 | /// that are appropriate for the allocation. | 
| Sebastian Redl | 00e68e2 | 2009-02-09 18:24:27 +0000 | [diff] [blame] | 1230 | bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, | 
 | 1231 |                                    bool UseGlobal, QualType AllocType, | 
 | 1232 |                                    bool IsArray, Expr **PlaceArgs, | 
 | 1233 |                                    unsigned NumPlaceArgs, | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1234 |                                    FunctionDecl *&OperatorNew, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1235 |                                    FunctionDecl *&OperatorDelete) { | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1236 |   // --- Choosing an allocation function --- | 
 | 1237 |   // C++ 5.3.4p8 - 14 & 18 | 
 | 1238 |   // 1) If UseGlobal is true, only look in the global scope. Else, also look | 
 | 1239 |   //   in the scope of the allocated class. | 
 | 1240 |   // 2) If an array size is given, look for operator new[], else look for | 
 | 1241 |   //   operator new. | 
 | 1242 |   // 3) The first argument is always size_t. Append the arguments from the | 
 | 1243 |   //   placement form. | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1244 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1245 |   SmallVector<Expr*, 8> AllocArgs(1 + NumPlaceArgs); | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1246 |   // We don't care about the actual value of this argument. | 
 | 1247 |   // FIXME: Should the Sema create the expression and embed it in the syntax | 
 | 1248 |   // tree? Or should the consumer just recalculate the value? | 
| Argyrios Kyrtzidis | 9996a7f | 2010-08-28 09:06:06 +0000 | [diff] [blame] | 1249 |   IntegerLiteral Size(Context, llvm::APInt::getNullValue( | 
| Douglas Gregor | bcfd1f5 | 2011-09-02 00:18:52 +0000 | [diff] [blame] | 1250 |                       Context.getTargetInfo().getPointerWidth(0)), | 
| Anders Carlsson | d67c4c3 | 2009-08-16 20:29:29 +0000 | [diff] [blame] | 1251 |                       Context.getSizeType(), | 
 | 1252 |                       SourceLocation()); | 
 | 1253 |   AllocArgs[0] = &Size; | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1254 |   std::copy(PlaceArgs, PlaceArgs + NumPlaceArgs, AllocArgs.begin() + 1); | 
 | 1255 |  | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1256 |   // C++ [expr.new]p8: | 
 | 1257 |   //   If the allocated type is a non-array type, the allocation | 
| NAKAMURA Takumi | 0099530 | 2011-01-27 07:09:49 +0000 | [diff] [blame] | 1258 |   //   function's name is operator new and the deallocation function's | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1259 |   //   name is operator delete. If the allocated type is an array | 
| NAKAMURA Takumi | 0099530 | 2011-01-27 07:09:49 +0000 | [diff] [blame] | 1260 |   //   type, the allocation function's name is operator new[] and the | 
 | 1261 |   //   deallocation function's name is operator delete[]. | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1262 |   DeclarationName NewName = Context.DeclarationNames.getCXXOperatorName( | 
 | 1263 |                                         IsArray ? OO_Array_New : OO_New); | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1264 |   DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName( | 
 | 1265 |                                         IsArray ? OO_Array_Delete : OO_Delete); | 
 | 1266 |  | 
| Argyrios Kyrtzidis | d293298 | 2010-08-25 23:14:56 +0000 | [diff] [blame] | 1267 |   QualType AllocElemType = Context.getBaseElementType(AllocType); | 
 | 1268 |  | 
 | 1269 |   if (AllocElemType->isRecordType() && !UseGlobal) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1270 |     CXXRecordDecl *Record | 
| Argyrios Kyrtzidis | d293298 | 2010-08-25 23:14:56 +0000 | [diff] [blame] | 1271 |       = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl()); | 
| Sebastian Redl | 00e68e2 | 2009-02-09 18:24:27 +0000 | [diff] [blame] | 1272 |     if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0], | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1273 |                           AllocArgs.size(), Record, /*AllowMissing=*/true, | 
 | 1274 |                           OperatorNew)) | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1275 |       return true; | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1276 |   } | 
 | 1277 |   if (!OperatorNew) { | 
 | 1278 |     // Didn't find a member overload. Look for a global one. | 
 | 1279 |     DeclareGlobalNewDelete(); | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1280 |     DeclContext *TUDecl = Context.getTranslationUnitDecl(); | 
| Sebastian Redl | 00e68e2 | 2009-02-09 18:24:27 +0000 | [diff] [blame] | 1281 |     if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0], | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1282 |                           AllocArgs.size(), TUDecl, /*AllowMissing=*/false, | 
 | 1283 |                           OperatorNew)) | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1284 |       return true; | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1285 |   } | 
 | 1286 |  | 
| John McCall | 9c82afc | 2010-04-20 02:18:25 +0000 | [diff] [blame] | 1287 |   // We don't need an operator delete if we're running under | 
 | 1288 |   // -fno-exceptions. | 
 | 1289 |   if (!getLangOptions().Exceptions) { | 
 | 1290 |     OperatorDelete = 0; | 
 | 1291 |     return false; | 
 | 1292 |   } | 
 | 1293 |  | 
| Anders Carlsson | d958389 | 2009-05-31 20:26:12 +0000 | [diff] [blame] | 1294 |   // FindAllocationOverload can change the passed in arguments, so we need to | 
 | 1295 |   // copy them back. | 
 | 1296 |   if (NumPlaceArgs > 0) | 
 | 1297 |     std::copy(&AllocArgs[1], AllocArgs.end(), PlaceArgs); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1298 |  | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1299 |   // C++ [expr.new]p19: | 
 | 1300 |   // | 
 | 1301 |   //   If the new-expression begins with a unary :: operator, the | 
| NAKAMURA Takumi | 0099530 | 2011-01-27 07:09:49 +0000 | [diff] [blame] | 1302 |   //   deallocation function's name is looked up in the global | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1303 |   //   scope. Otherwise, if the allocated type is a class type T or an | 
| NAKAMURA Takumi | 0099530 | 2011-01-27 07:09:49 +0000 | [diff] [blame] | 1304 |   //   array thereof, the deallocation function's name is looked up in | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1305 |   //   the scope of T. If this lookup fails to find the name, or if | 
 | 1306 |   //   the allocated type is not a class type or array thereof, the | 
| NAKAMURA Takumi | 0099530 | 2011-01-27 07:09:49 +0000 | [diff] [blame] | 1307 |   //   deallocation function's name is looked up in the global scope. | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1308 |   LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName); | 
| Argyrios Kyrtzidis | d293298 | 2010-08-25 23:14:56 +0000 | [diff] [blame] | 1309 |   if (AllocElemType->isRecordType() && !UseGlobal) { | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1310 |     CXXRecordDecl *RD | 
| Argyrios Kyrtzidis | d293298 | 2010-08-25 23:14:56 +0000 | [diff] [blame] | 1311 |       = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl()); | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1312 |     LookupQualifiedName(FoundDelete, RD); | 
 | 1313 |   } | 
| John McCall | 90c8c57 | 2010-03-18 08:19:33 +0000 | [diff] [blame] | 1314 |   if (FoundDelete.isAmbiguous()) | 
 | 1315 |     return true; // FIXME: clean up expressions? | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1316 |  | 
 | 1317 |   if (FoundDelete.empty()) { | 
 | 1318 |     DeclareGlobalNewDelete(); | 
 | 1319 |     LookupQualifiedName(FoundDelete, Context.getTranslationUnitDecl()); | 
 | 1320 |   } | 
 | 1321 |  | 
 | 1322 |   FoundDelete.suppressDiagnostics(); | 
| John McCall | 9aa472c | 2010-03-19 07:35:19 +0000 | [diff] [blame] | 1323 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1324 |   SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches; | 
| John McCall | 9aa472c | 2010-03-19 07:35:19 +0000 | [diff] [blame] | 1325 |  | 
| John McCall | edeb6c9 | 2010-09-14 21:34:24 +0000 | [diff] [blame] | 1326 |   // Whether we're looking for a placement operator delete is dictated | 
 | 1327 |   // by whether we selected a placement operator new, not by whether | 
 | 1328 |   // we had explicit placement arguments.  This matters for things like | 
 | 1329 |   //   struct A { void *operator new(size_t, int = 0); ... }; | 
 | 1330 |   //   A *a = new A() | 
 | 1331 |   bool isPlacementNew = (NumPlaceArgs > 0 || OperatorNew->param_size() != 1); | 
 | 1332 |  | 
 | 1333 |   if (isPlacementNew) { | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1334 |     // C++ [expr.new]p20: | 
 | 1335 |     //   A declaration of a placement deallocation function matches the | 
 | 1336 |     //   declaration of a placement allocation function if it has the | 
 | 1337 |     //   same number of parameters and, after parameter transformations | 
 | 1338 |     //   (8.3.5), all parameter types except the first are | 
 | 1339 |     //   identical. [...] | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1340 |     // | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1341 |     // To perform this comparison, we compute the function type that | 
 | 1342 |     // the deallocation function should have, and use that type both | 
 | 1343 |     // for template argument deduction and for comparison purposes. | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 1344 |     // | 
 | 1345 |     // FIXME: this comparison should ignore CC and the like. | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1346 |     QualType ExpectedFunctionType; | 
 | 1347 |     { | 
 | 1348 |       const FunctionProtoType *Proto | 
 | 1349 |         = OperatorNew->getType()->getAs<FunctionProtoType>(); | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 1350 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1351 |       SmallVector<QualType, 4> ArgTypes; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1352 |       ArgTypes.push_back(Context.VoidPtrTy); | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1353 |       for (unsigned I = 1, N = Proto->getNumArgs(); I < N; ++I) | 
 | 1354 |         ArgTypes.push_back(Proto->getArgType(I)); | 
 | 1355 |  | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 1356 |       FunctionProtoType::ExtProtoInfo EPI; | 
 | 1357 |       EPI.Variadic = Proto->isVariadic(); | 
 | 1358 |  | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1359 |       ExpectedFunctionType | 
 | 1360 |         = Context.getFunctionType(Context.VoidTy, ArgTypes.data(), | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 1361 |                                   ArgTypes.size(), EPI); | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1362 |     } | 
 | 1363 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1364 |     for (LookupResult::iterator D = FoundDelete.begin(), | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1365 |                              DEnd = FoundDelete.end(); | 
 | 1366 |          D != DEnd; ++D) { | 
 | 1367 |       FunctionDecl *Fn = 0; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1368 |       if (FunctionTemplateDecl *FnTmpl | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1369 |             = dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) { | 
 | 1370 |         // Perform template argument deduction to try to match the | 
 | 1371 |         // expected function type. | 
 | 1372 |         TemplateDeductionInfo Info(Context, StartLoc); | 
 | 1373 |         if (DeduceTemplateArguments(FnTmpl, 0, ExpectedFunctionType, Fn, Info)) | 
 | 1374 |           continue; | 
 | 1375 |       } else | 
 | 1376 |         Fn = cast<FunctionDecl>((*D)->getUnderlyingDecl()); | 
 | 1377 |  | 
 | 1378 |       if (Context.hasSameType(Fn->getType(), ExpectedFunctionType)) | 
| John McCall | 9aa472c | 2010-03-19 07:35:19 +0000 | [diff] [blame] | 1379 |         Matches.push_back(std::make_pair(D.getPair(), Fn)); | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1380 |     } | 
 | 1381 |   } else { | 
 | 1382 |     // C++ [expr.new]p20: | 
 | 1383 |     //   [...] Any non-placement deallocation function matches a | 
 | 1384 |     //   non-placement allocation function. [...] | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1385 |     for (LookupResult::iterator D = FoundDelete.begin(), | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1386 |                              DEnd = FoundDelete.end(); | 
 | 1387 |          D != DEnd; ++D) { | 
 | 1388 |       if (FunctionDecl *Fn = dyn_cast<FunctionDecl>((*D)->getUnderlyingDecl())) | 
 | 1389 |         if (isNonPlacementDeallocationFunction(Fn)) | 
| John McCall | 9aa472c | 2010-03-19 07:35:19 +0000 | [diff] [blame] | 1390 |           Matches.push_back(std::make_pair(D.getPair(), Fn)); | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1391 |     } | 
 | 1392 |   } | 
 | 1393 |  | 
 | 1394 |   // C++ [expr.new]p20: | 
 | 1395 |   //   [...] If the lookup finds a single matching deallocation | 
 | 1396 |   //   function, that function will be called; otherwise, no | 
 | 1397 |   //   deallocation function will be called. | 
 | 1398 |   if (Matches.size() == 1) { | 
| John McCall | 9aa472c | 2010-03-19 07:35:19 +0000 | [diff] [blame] | 1399 |     OperatorDelete = Matches[0].second; | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1400 |  | 
 | 1401 |     // C++0x [expr.new]p20: | 
 | 1402 |     //   If the lookup finds the two-parameter form of a usual | 
 | 1403 |     //   deallocation function (3.7.4.2) and that function, considered | 
 | 1404 |     //   as a placement deallocation function, would have been | 
 | 1405 |     //   selected as a match for the allocation function, the program | 
 | 1406 |     //   is ill-formed. | 
 | 1407 |     if (NumPlaceArgs && getLangOptions().CPlusPlus0x && | 
 | 1408 |         isNonPlacementDeallocationFunction(OperatorDelete)) { | 
 | 1409 |       Diag(StartLoc, diag::err_placement_new_non_placement_delete) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1410 |         << SourceRange(PlaceArgs[0]->getLocStart(), | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1411 |                        PlaceArgs[NumPlaceArgs - 1]->getLocEnd()); | 
 | 1412 |       Diag(OperatorDelete->getLocation(), diag::note_previous_decl) | 
 | 1413 |         << DeleteName; | 
| John McCall | 90c8c57 | 2010-03-18 08:19:33 +0000 | [diff] [blame] | 1414 |     } else { | 
 | 1415 |       CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(), | 
| John McCall | 9aa472c | 2010-03-19 07:35:19 +0000 | [diff] [blame] | 1416 |                             Matches[0].first); | 
| Douglas Gregor | 6d90870 | 2010-02-26 05:06:18 +0000 | [diff] [blame] | 1417 |     } | 
 | 1418 |   } | 
 | 1419 |  | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1420 |   return false; | 
 | 1421 | } | 
 | 1422 |  | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1423 | /// FindAllocationOverload - Find an fitting overload for the allocation | 
 | 1424 | /// function in the specified scope. | 
| Sebastian Redl | 00e68e2 | 2009-02-09 18:24:27 +0000 | [diff] [blame] | 1425 | bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, | 
 | 1426 |                                   DeclarationName Name, Expr** Args, | 
 | 1427 |                                   unsigned NumArgs, DeclContext *Ctx, | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1428 |                                   bool AllowMissing, FunctionDecl *&Operator, | 
 | 1429 |                                   bool Diagnose) { | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 1430 |   LookupResult R(*this, Name, StartLoc, LookupOrdinaryName); | 
 | 1431 |   LookupQualifiedName(R, Ctx); | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 1432 |   if (R.empty()) { | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1433 |     if (AllowMissing || !Diagnose) | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1434 |       return false; | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1435 |     return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call) | 
| Chris Lattner | 4330d65 | 2009-02-17 07:29:20 +0000 | [diff] [blame] | 1436 |       << Name << Range; | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1437 |   } | 
 | 1438 |  | 
| John McCall | 90c8c57 | 2010-03-18 08:19:33 +0000 | [diff] [blame] | 1439 |   if (R.isAmbiguous()) | 
 | 1440 |     return true; | 
 | 1441 |  | 
 | 1442 |   R.suppressDiagnostics(); | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 1443 |  | 
| John McCall | 5769d61 | 2010-02-08 23:07:23 +0000 | [diff] [blame] | 1444 |   OverloadCandidateSet Candidates(StartLoc); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1445 |   for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end(); | 
| Douglas Gregor | 5d64e5b | 2009-09-30 00:03:47 +0000 | [diff] [blame] | 1446 |        Alloc != AllocEnd; ++Alloc) { | 
| Douglas Gregor | 3fc749d | 2008-12-23 00:26:44 +0000 | [diff] [blame] | 1447 |     // Even member operator new/delete are implicitly treated as | 
 | 1448 |     // static, so don't use AddMemberCandidate. | 
| John McCall | 9aa472c | 2010-03-19 07:35:19 +0000 | [diff] [blame] | 1449 |     NamedDecl *D = (*Alloc)->getUnderlyingDecl(); | 
| Chandler Carruth | 4a73ea9 | 2010-02-03 11:02:14 +0000 | [diff] [blame] | 1450 |  | 
| John McCall | 9aa472c | 2010-03-19 07:35:19 +0000 | [diff] [blame] | 1451 |     if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) { | 
 | 1452 |       AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(), | 
| Chandler Carruth | 4a73ea9 | 2010-02-03 11:02:14 +0000 | [diff] [blame] | 1453 |                                    /*ExplicitTemplateArgs=*/0, Args, NumArgs, | 
 | 1454 |                                    Candidates, | 
 | 1455 |                                    /*SuppressUserConversions=*/false); | 
| Douglas Gregor | 9091656 | 2009-09-29 18:16:17 +0000 | [diff] [blame] | 1456 |       continue; | 
| Chandler Carruth | 4a73ea9 | 2010-02-03 11:02:14 +0000 | [diff] [blame] | 1457 |     } | 
 | 1458 |  | 
| John McCall | 9aa472c | 2010-03-19 07:35:19 +0000 | [diff] [blame] | 1459 |     FunctionDecl *Fn = cast<FunctionDecl>(D); | 
 | 1460 |     AddOverloadCandidate(Fn, Alloc.getPair(), Args, NumArgs, Candidates, | 
| Chandler Carruth | 4a73ea9 | 2010-02-03 11:02:14 +0000 | [diff] [blame] | 1461 |                          /*SuppressUserConversions=*/false); | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1462 |   } | 
 | 1463 |  | 
 | 1464 |   // Do the resolution. | 
 | 1465 |   OverloadCandidateSet::iterator Best; | 
| John McCall | 120d63c | 2010-08-24 20:38:10 +0000 | [diff] [blame] | 1466 |   switch (Candidates.BestViableFunction(*this, StartLoc, Best)) { | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1467 |   case OR_Success: { | 
 | 1468 |     // Got one! | 
 | 1469 |     FunctionDecl *FnDecl = Best->Function; | 
| Chandler Carruth | 25ca421 | 2011-02-25 19:41:05 +0000 | [diff] [blame] | 1470 |     MarkDeclarationReferenced(StartLoc, FnDecl); | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1471 |     // The first argument is size_t, and the first parameter must be size_t, | 
 | 1472 |     // too. This is checked on declaration and can be assumed. (It can't be | 
 | 1473 |     // asserted on, though, since invalid decls are left in there.) | 
| John McCall | 90c8c57 | 2010-03-18 08:19:33 +0000 | [diff] [blame] | 1474 |     // Watch out for variadic allocator function. | 
| Fariborz Jahanian | 048f52a | 2009-11-24 18:29:37 +0000 | [diff] [blame] | 1475 |     unsigned NumArgsInFnDecl = FnDecl->getNumParams(); | 
 | 1476 |     for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) { | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1477 |       InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, | 
 | 1478 |                                                        FnDecl->getParamDecl(i)); | 
 | 1479 |  | 
 | 1480 |       if (!Diagnose && !CanPerformCopyInitialization(Entity, Owned(Args[i]))) | 
 | 1481 |         return true; | 
 | 1482 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 1483 |       ExprResult Result | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1484 |         = PerformCopyInitialization(Entity, SourceLocation(), Owned(Args[i])); | 
| Douglas Gregor | 29ecaba | 2010-03-26 20:35:59 +0000 | [diff] [blame] | 1485 |       if (Result.isInvalid()) | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1486 |         return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1487 |  | 
| Douglas Gregor | 29ecaba | 2010-03-26 20:35:59 +0000 | [diff] [blame] | 1488 |       Args[i] = Result.takeAs<Expr>(); | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1489 |     } | 
 | 1490 |     Operator = FnDecl; | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1491 |     CheckAllocationAccess(StartLoc, Range, R.getNamingClass(), Best->FoundDecl, | 
 | 1492 |                           Diagnose); | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1493 |     return false; | 
 | 1494 |   } | 
 | 1495 |  | 
 | 1496 |   case OR_No_Viable_Function: | 
| Chandler Carruth | 361d380 | 2011-06-08 10:26:03 +0000 | [diff] [blame] | 1497 |     if (Diagnose) { | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1498 |       Diag(StartLoc, diag::err_ovl_no_viable_function_in_call) | 
 | 1499 |         << Name << Range; | 
| Chandler Carruth | 361d380 | 2011-06-08 10:26:03 +0000 | [diff] [blame] | 1500 |       Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs); | 
 | 1501 |     } | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1502 |     return true; | 
 | 1503 |  | 
 | 1504 |   case OR_Ambiguous: | 
| Chandler Carruth | 361d380 | 2011-06-08 10:26:03 +0000 | [diff] [blame] | 1505 |     if (Diagnose) { | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1506 |       Diag(StartLoc, diag::err_ovl_ambiguous_call) | 
 | 1507 |         << Name << Range; | 
| Chandler Carruth | 361d380 | 2011-06-08 10:26:03 +0000 | [diff] [blame] | 1508 |       Candidates.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs); | 
 | 1509 |     } | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1510 |     return true; | 
| Douglas Gregor | 48f3bb9 | 2009-02-18 21:56:37 +0000 | [diff] [blame] | 1511 |  | 
| Douglas Gregor | 0a0d2b1 | 2011-03-23 00:50:03 +0000 | [diff] [blame] | 1512 |   case OR_Deleted: { | 
| Chandler Carruth | 361d380 | 2011-06-08 10:26:03 +0000 | [diff] [blame] | 1513 |     if (Diagnose) { | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1514 |       Diag(StartLoc, diag::err_ovl_deleted_call) | 
 | 1515 |         << Best->Function->isDeleted() | 
 | 1516 |         << Name  | 
 | 1517 |         << getDeletedOrUnavailableSuffix(Best->Function) | 
 | 1518 |         << Range; | 
| Chandler Carruth | 361d380 | 2011-06-08 10:26:03 +0000 | [diff] [blame] | 1519 |       Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs); | 
 | 1520 |     } | 
| Douglas Gregor | 48f3bb9 | 2009-02-18 21:56:37 +0000 | [diff] [blame] | 1521 |     return true; | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1522 |   } | 
| Douglas Gregor | 0a0d2b1 | 2011-03-23 00:50:03 +0000 | [diff] [blame] | 1523 |   } | 
| David Blaikie | b219cfc | 2011-09-23 05:06:16 +0000 | [diff] [blame] | 1524 |   llvm_unreachable("Unreachable, bad result from BestViableFunction"); | 
| Sebastian Redl | 7f66239 | 2008-12-04 22:20:51 +0000 | [diff] [blame] | 1525 | } | 
 | 1526 |  | 
 | 1527 |  | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1528 | /// DeclareGlobalNewDelete - Declare the global forms of operator new and | 
 | 1529 | /// delete. These are: | 
 | 1530 | /// @code | 
| Sebastian Redl | 8999fe1 | 2011-03-14 18:08:30 +0000 | [diff] [blame] | 1531 | ///   // C++03: | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1532 | ///   void* operator new(std::size_t) throw(std::bad_alloc); | 
 | 1533 | ///   void* operator new[](std::size_t) throw(std::bad_alloc); | 
 | 1534 | ///   void operator delete(void *) throw(); | 
 | 1535 | ///   void operator delete[](void *) throw(); | 
| Sebastian Redl | 8999fe1 | 2011-03-14 18:08:30 +0000 | [diff] [blame] | 1536 | ///   // C++0x: | 
 | 1537 | ///   void* operator new(std::size_t); | 
 | 1538 | ///   void* operator new[](std::size_t); | 
 | 1539 | ///   void operator delete(void *); | 
 | 1540 | ///   void operator delete[](void *); | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1541 | /// @endcode | 
| Sebastian Redl | 8999fe1 | 2011-03-14 18:08:30 +0000 | [diff] [blame] | 1542 | /// C++0x operator delete is implicitly noexcept. | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1543 | /// Note that the placement and nothrow forms of new are *not* implicitly | 
 | 1544 | /// declared. Their use requires including \<new\>. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1545 | void Sema::DeclareGlobalNewDelete() { | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1546 |   if (GlobalNewDeleteDeclared) | 
 | 1547 |     return; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1548 |  | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1549 |   // C++ [basic.std.dynamic]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1550 |   //   [...] The following allocation and deallocation functions (18.4) are | 
 | 1551 |   //   implicitly declared in global scope in each translation unit of a | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1552 |   //   program | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1553 |   // | 
| Sebastian Redl | 8999fe1 | 2011-03-14 18:08:30 +0000 | [diff] [blame] | 1554 |   //     C++03: | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1555 |   //     void* operator new(std::size_t) throw(std::bad_alloc); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1556 |   //     void* operator new[](std::size_t) throw(std::bad_alloc); | 
 | 1557 |   //     void  operator delete(void*) throw(); | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1558 |   //     void  operator delete[](void*) throw(); | 
| Sebastian Redl | 8999fe1 | 2011-03-14 18:08:30 +0000 | [diff] [blame] | 1559 |   //     C++0x: | 
 | 1560 |   //     void* operator new(std::size_t); | 
 | 1561 |   //     void* operator new[](std::size_t); | 
 | 1562 |   //     void  operator delete(void*); | 
 | 1563 |   //     void  operator delete[](void*); | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1564 |   // | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1565 |   //   These implicit declarations introduce only the function names operator | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1566 |   //   new, operator new[], operator delete, operator delete[]. | 
 | 1567 |   // | 
 | 1568 |   // Here, we need to refer to std::bad_alloc, so we will implicitly declare | 
 | 1569 |   // "std" or "bad_alloc" as necessary to form the exception specification. | 
 | 1570 |   // However, we do not make these implicit declarations visible to name | 
 | 1571 |   // lookup. | 
| Sebastian Redl | 8999fe1 | 2011-03-14 18:08:30 +0000 | [diff] [blame] | 1572 |   // Note that the C++0x versions of operator delete are deallocation functions, | 
 | 1573 |   // and thus are implicitly noexcept. | 
 | 1574 |   if (!StdBadAlloc && !getLangOptions().CPlusPlus0x) { | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1575 |     // The "std::bad_alloc" class has not yet been declared, so build it | 
 | 1576 |     // implicitly. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1577 |     StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class, | 
 | 1578 |                                         getOrCreateStdNamespace(), | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 1579 |                                         SourceLocation(), SourceLocation(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1580 |                                       &PP.getIdentifierTable().get("bad_alloc"), | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 1581 |                                         0); | 
| Argyrios Kyrtzidis | 76c38d3 | 2010-08-02 07:14:54 +0000 | [diff] [blame] | 1582 |     getStdBadAlloc()->setImplicit(true); | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1583 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1584 |  | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1585 |   GlobalNewDeleteDeclared = true; | 
 | 1586 |  | 
 | 1587 |   QualType VoidPtr = Context.getPointerType(Context.VoidTy); | 
 | 1588 |   QualType SizeT = Context.getSizeType(); | 
| Nuno Lopes | fc28448 | 2009-12-16 16:59:22 +0000 | [diff] [blame] | 1589 |   bool AssumeSaneOperatorNew = getLangOptions().AssumeSaneOperatorNew; | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1590 |  | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1591 |   DeclareGlobalAllocationFunction( | 
 | 1592 |       Context.DeclarationNames.getCXXOperatorName(OO_New), | 
| Nuno Lopes | fc28448 | 2009-12-16 16:59:22 +0000 | [diff] [blame] | 1593 |       VoidPtr, SizeT, AssumeSaneOperatorNew); | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1594 |   DeclareGlobalAllocationFunction( | 
 | 1595 |       Context.DeclarationNames.getCXXOperatorName(OO_Array_New), | 
| Nuno Lopes | fc28448 | 2009-12-16 16:59:22 +0000 | [diff] [blame] | 1596 |       VoidPtr, SizeT, AssumeSaneOperatorNew); | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1597 |   DeclareGlobalAllocationFunction( | 
 | 1598 |       Context.DeclarationNames.getCXXOperatorName(OO_Delete), | 
 | 1599 |       Context.VoidTy, VoidPtr); | 
 | 1600 |   DeclareGlobalAllocationFunction( | 
 | 1601 |       Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete), | 
 | 1602 |       Context.VoidTy, VoidPtr); | 
 | 1603 | } | 
 | 1604 |  | 
 | 1605 | /// DeclareGlobalAllocationFunction - Declares a single implicit global | 
 | 1606 | /// allocation function if it doesn't already exist. | 
 | 1607 | void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, | 
| Nuno Lopes | fc28448 | 2009-12-16 16:59:22 +0000 | [diff] [blame] | 1608 |                                            QualType Return, QualType Argument, | 
 | 1609 |                                            bool AddMallocAttr) { | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1610 |   DeclContext *GlobalCtx = Context.getTranslationUnitDecl(); | 
 | 1611 |  | 
 | 1612 |   // Check if this function is already declared. | 
| Douglas Gregor | 6ed40e3 | 2008-12-23 21:05:05 +0000 | [diff] [blame] | 1613 |   { | 
| Douglas Gregor | 5cc3709 | 2008-12-23 22:05:29 +0000 | [diff] [blame] | 1614 |     DeclContext::lookup_iterator Alloc, AllocEnd; | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 1615 |     for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Name); | 
| Douglas Gregor | 6ed40e3 | 2008-12-23 21:05:05 +0000 | [diff] [blame] | 1616 |          Alloc != AllocEnd; ++Alloc) { | 
| Chandler Carruth | 4a73ea9 | 2010-02-03 11:02:14 +0000 | [diff] [blame] | 1617 |       // Only look at non-template functions, as it is the predefined, | 
 | 1618 |       // non-templated allocation function we are trying to declare here. | 
 | 1619 |       if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*Alloc)) { | 
 | 1620 |         QualType InitialParamType = | 
| Douglas Gregor | 6e790ab | 2009-12-22 23:42:49 +0000 | [diff] [blame] | 1621 |           Context.getCanonicalType( | 
| Chandler Carruth | 4a73ea9 | 2010-02-03 11:02:14 +0000 | [diff] [blame] | 1622 |             Func->getParamDecl(0)->getType().getUnqualifiedType()); | 
 | 1623 |         // FIXME: Do we need to check for default arguments here? | 
| Douglas Gregor | 7b86862 | 2010-08-18 15:06:25 +0000 | [diff] [blame] | 1624 |         if (Func->getNumParams() == 1 && InitialParamType == Argument) { | 
 | 1625 |           if(AddMallocAttr && !Func->hasAttr<MallocAttr>()) | 
| Sean Hunt | cf807c4 | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 1626 |             Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context)); | 
| Chandler Carruth | 4a73ea9 | 2010-02-03 11:02:14 +0000 | [diff] [blame] | 1627 |           return; | 
| Douglas Gregor | 7b86862 | 2010-08-18 15:06:25 +0000 | [diff] [blame] | 1628 |         } | 
| Chandler Carruth | 4a73ea9 | 2010-02-03 11:02:14 +0000 | [diff] [blame] | 1629 |       } | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1630 |     } | 
 | 1631 |   } | 
 | 1632 |  | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1633 |   QualType BadAllocType; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1634 |   bool HasBadAllocExceptionSpec | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1635 |     = (Name.getCXXOverloadedOperator() == OO_New || | 
 | 1636 |        Name.getCXXOverloadedOperator() == OO_Array_New); | 
| Sebastian Redl | 8999fe1 | 2011-03-14 18:08:30 +0000 | [diff] [blame] | 1637 |   if (HasBadAllocExceptionSpec && !getLangOptions().CPlusPlus0x) { | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1638 |     assert(StdBadAlloc && "Must have std::bad_alloc declared"); | 
| Argyrios Kyrtzidis | 76c38d3 | 2010-08-02 07:14:54 +0000 | [diff] [blame] | 1639 |     BadAllocType = Context.getTypeDeclType(getStdBadAlloc()); | 
| Douglas Gregor | 7adb10f | 2009-09-15 22:30:29 +0000 | [diff] [blame] | 1640 |   } | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 1641 |  | 
 | 1642 |   FunctionProtoType::ExtProtoInfo EPI; | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 1643 |   if (HasBadAllocExceptionSpec) { | 
| Sebastian Redl | 8999fe1 | 2011-03-14 18:08:30 +0000 | [diff] [blame] | 1644 |     if (!getLangOptions().CPlusPlus0x) { | 
 | 1645 |       EPI.ExceptionSpecType = EST_Dynamic; | 
 | 1646 |       EPI.NumExceptions = 1; | 
 | 1647 |       EPI.Exceptions = &BadAllocType; | 
 | 1648 |     } | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 1649 |   } else { | 
| Sebastian Redl | 8999fe1 | 2011-03-14 18:08:30 +0000 | [diff] [blame] | 1650 |     EPI.ExceptionSpecType = getLangOptions().CPlusPlus0x ? | 
 | 1651 |                                 EST_BasicNoexcept : EST_DynamicNone; | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 1652 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1653 |  | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 1654 |   QualType FnType = Context.getFunctionType(Return, &Argument, 1, EPI); | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1655 |   FunctionDecl *Alloc = | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1656 |     FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), | 
 | 1657 |                          SourceLocation(), Name, | 
| John McCall | d931b08 | 2010-08-26 03:08:43 +0000 | [diff] [blame] | 1658 |                          FnType, /*TInfo=*/0, SC_None, | 
 | 1659 |                          SC_None, false, true); | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1660 |   Alloc->setImplicit(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1661 |  | 
| Nuno Lopes | fc28448 | 2009-12-16 16:59:22 +0000 | [diff] [blame] | 1662 |   if (AddMallocAttr) | 
| Sean Hunt | cf807c4 | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 1663 |     Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context)); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1664 |  | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1665 |   ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(), | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1666 |                                            SourceLocation(), 0, | 
 | 1667 |                                            Argument, /*TInfo=*/0, | 
 | 1668 |                                            SC_None, SC_None, 0); | 
| David Blaikie | 4278c65 | 2011-09-21 18:16:56 +0000 | [diff] [blame] | 1669 |   Alloc->setParams(Param); | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1670 |  | 
| Douglas Gregor | 6ed40e3 | 2008-12-23 21:05:05 +0000 | [diff] [blame] | 1671 |   // FIXME: Also add this declaration to the IdentifierResolver, but | 
 | 1672 |   // make sure it is at the end of the chain to coincide with the | 
 | 1673 |   // global scope. | 
| John McCall | 5f1e094 | 2010-08-24 08:50:51 +0000 | [diff] [blame] | 1674 |   Context.getTranslationUnitDecl()->addDecl(Alloc); | 
| Sebastian Redl | b5a57a6 | 2008-12-03 20:26:15 +0000 | [diff] [blame] | 1675 | } | 
 | 1676 |  | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1677 | bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, | 
 | 1678 |                                     DeclarationName Name, | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1679 |                                     FunctionDecl* &Operator, bool Diagnose) { | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 1680 |   LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName); | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1681 |   // Try to find operator delete/operator delete[] in class scope. | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 1682 |   LookupQualifiedName(Found, RD); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1683 |  | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 1684 |   if (Found.isAmbiguous()) | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1685 |     return true; | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1686 |  | 
| Chandler Carruth | 2389324 | 2010-06-28 00:30:51 +0000 | [diff] [blame] | 1687 |   Found.suppressDiagnostics(); | 
 | 1688 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1689 |   SmallVector<DeclAccessPair,4> Matches; | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1690 |   for (LookupResult::iterator F = Found.begin(), FEnd = Found.end(); | 
 | 1691 |        F != FEnd; ++F) { | 
| Chandler Carruth | 09556fd | 2010-08-08 07:04:00 +0000 | [diff] [blame] | 1692 |     NamedDecl *ND = (*F)->getUnderlyingDecl(); | 
 | 1693 |  | 
 | 1694 |     // Ignore template operator delete members from the check for a usual | 
 | 1695 |     // deallocation function. | 
 | 1696 |     if (isa<FunctionTemplateDecl>(ND)) | 
 | 1697 |       continue; | 
 | 1698 |  | 
 | 1699 |     if (cast<CXXMethodDecl>(ND)->isUsualDeallocationFunction()) | 
| John McCall | 046a746 | 2010-08-04 00:31:26 +0000 | [diff] [blame] | 1700 |       Matches.push_back(F.getPair()); | 
 | 1701 |   } | 
 | 1702 |  | 
 | 1703 |   // There's exactly one suitable operator;  pick it. | 
 | 1704 |   if (Matches.size() == 1) { | 
 | 1705 |     Operator = cast<CXXMethodDecl>(Matches[0]->getUnderlyingDecl()); | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1706 |  | 
 | 1707 |     if (Operator->isDeleted()) { | 
 | 1708 |       if (Diagnose) { | 
 | 1709 |         Diag(StartLoc, diag::err_deleted_function_use); | 
 | 1710 |         Diag(Operator->getLocation(), diag::note_unavailable_here) << true; | 
 | 1711 |       } | 
 | 1712 |       return true; | 
 | 1713 |     } | 
 | 1714 |  | 
| John McCall | 046a746 | 2010-08-04 00:31:26 +0000 | [diff] [blame] | 1715 |     CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(), | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1716 |                           Matches[0], Diagnose); | 
| John McCall | 046a746 | 2010-08-04 00:31:26 +0000 | [diff] [blame] | 1717 |     return false; | 
 | 1718 |  | 
 | 1719 |   // We found multiple suitable operators;  complain about the ambiguity. | 
 | 1720 |   } else if (!Matches.empty()) { | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1721 |     if (Diagnose) { | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 1722 |       Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found) | 
 | 1723 |         << Name << RD; | 
| John McCall | 046a746 | 2010-08-04 00:31:26 +0000 | [diff] [blame] | 1724 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1725 |       for (SmallVectorImpl<DeclAccessPair>::iterator | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 1726 |              F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F) | 
 | 1727 |         Diag((*F)->getUnderlyingDecl()->getLocation(), | 
 | 1728 |              diag::note_member_declared_here) << Name; | 
 | 1729 |     } | 
| John McCall | 046a746 | 2010-08-04 00:31:26 +0000 | [diff] [blame] | 1730 |     return true; | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1731 |   } | 
 | 1732 |  | 
 | 1733 |   // We did find operator delete/operator delete[] declarations, but | 
 | 1734 |   // none of them were suitable. | 
 | 1735 |   if (!Found.empty()) { | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1736 |     if (Diagnose) { | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 1737 |       Diag(StartLoc, diag::err_no_suitable_delete_member_function_found) | 
 | 1738 |         << Name << RD; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1739 |  | 
| Sean Hunt | cb45a0f | 2011-05-12 22:46:25 +0000 | [diff] [blame] | 1740 |       for (LookupResult::iterator F = Found.begin(), FEnd = Found.end(); | 
 | 1741 |            F != FEnd; ++F) | 
 | 1742 |         Diag((*F)->getUnderlyingDecl()->getLocation(), | 
 | 1743 |              diag::note_member_declared_here) << Name; | 
 | 1744 |     } | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1745 |     return true; | 
 | 1746 |   } | 
 | 1747 |  | 
 | 1748 |   // Look for a global declaration. | 
 | 1749 |   DeclareGlobalNewDelete(); | 
 | 1750 |   DeclContext *TUDecl = Context.getTranslationUnitDecl(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1751 |  | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1752 |   CXXNullPtrLiteralExpr Null(Context.VoidPtrTy, SourceLocation()); | 
 | 1753 |   Expr* DeallocArgs[1]; | 
 | 1754 |   DeallocArgs[0] = &Null; | 
 | 1755 |   if (FindAllocationOverload(StartLoc, SourceRange(), Name, | 
| Sean Hunt | 2be7e90 | 2011-05-12 22:46:29 +0000 | [diff] [blame] | 1756 |                              DeallocArgs, 1, TUDecl, !Diagnose, | 
 | 1757 |                              Operator, Diagnose)) | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1758 |     return true; | 
 | 1759 |  | 
 | 1760 |   assert(Operator && "Did not find a deallocation function!"); | 
 | 1761 |   return false; | 
 | 1762 | } | 
 | 1763 |  | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1764 | /// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in: | 
 | 1765 | /// @code ::delete ptr; @endcode | 
 | 1766 | /// or | 
 | 1767 | /// @code delete [] ptr; @endcode | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 1768 | ExprResult | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1769 | Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1770 |                      bool ArrayForm, Expr *ExE) { | 
| Douglas Gregor | 9cd9f3f | 2009-09-09 23:39:55 +0000 | [diff] [blame] | 1771 |   // C++ [expr.delete]p1: | 
 | 1772 |   //   The operand shall have a pointer type, or a class type having a single | 
 | 1773 |   //   conversion function to a pointer type. The result has type void. | 
 | 1774 |   // | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1775 |   // DR599 amends "pointer type" to "pointer to object type" in both cases. | 
 | 1776 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1777 |   ExprResult Ex = Owned(ExE); | 
| Anders Carlsson | d67c4c3 | 2009-08-16 20:29:29 +0000 | [diff] [blame] | 1778 |   FunctionDecl *OperatorDelete = 0; | 
| Argyrios Kyrtzidis | 4076dac | 2010-09-13 20:15:54 +0000 | [diff] [blame] | 1779 |   bool ArrayFormAsWritten = ArrayForm; | 
| John McCall | 6ec278d | 2011-01-27 09:37:56 +0000 | [diff] [blame] | 1780 |   bool UsualArrayDeleteWantsSize = false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1781 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1782 |   if (!Ex.get()->isTypeDependent()) { | 
 | 1783 |     QualType Type = Ex.get()->getType(); | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1784 |  | 
| Douglas Gregor | 9cd9f3f | 2009-09-09 23:39:55 +0000 | [diff] [blame] | 1785 |     if (const RecordType *Record = Type->getAs<RecordType>()) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1786 |       if (RequireCompleteType(StartLoc, Type, | 
| Douglas Gregor | 254a942 | 2010-07-29 14:44:35 +0000 | [diff] [blame] | 1787 |                               PDiag(diag::err_delete_incomplete_class_type))) | 
 | 1788 |         return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1789 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1790 |       SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions; | 
| John McCall | 32daa42 | 2010-03-31 01:36:47 +0000 | [diff] [blame] | 1791 |  | 
| Fariborz Jahanian | 5346278 | 2009-09-11 21:44:33 +0000 | [diff] [blame] | 1792 |       CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1793 |       const UnresolvedSetImpl *Conversions = RD->getVisibleConversionFunctions(); | 
| John McCall | eec51cf | 2010-01-20 00:46:10 +0000 | [diff] [blame] | 1794 |       for (UnresolvedSetImpl::iterator I = Conversions->begin(), | 
| John McCall | ba13543 | 2009-11-21 08:51:07 +0000 | [diff] [blame] | 1795 |              E = Conversions->end(); I != E; ++I) { | 
| John McCall | 32daa42 | 2010-03-31 01:36:47 +0000 | [diff] [blame] | 1796 |         NamedDecl *D = I.getDecl(); | 
 | 1797 |         if (isa<UsingShadowDecl>(D)) | 
 | 1798 |           D = cast<UsingShadowDecl>(D)->getTargetDecl(); | 
 | 1799 |  | 
| Douglas Gregor | 9cd9f3f | 2009-09-09 23:39:55 +0000 | [diff] [blame] | 1800 |         // Skip over templated conversion functions; they aren't considered. | 
| John McCall | 32daa42 | 2010-03-31 01:36:47 +0000 | [diff] [blame] | 1801 |         if (isa<FunctionTemplateDecl>(D)) | 
| Douglas Gregor | 9cd9f3f | 2009-09-09 23:39:55 +0000 | [diff] [blame] | 1802 |           continue; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1803 |  | 
| John McCall | 32daa42 | 2010-03-31 01:36:47 +0000 | [diff] [blame] | 1804 |         CXXConversionDecl *Conv = cast<CXXConversionDecl>(D); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1805 |  | 
| Douglas Gregor | 9cd9f3f | 2009-09-09 23:39:55 +0000 | [diff] [blame] | 1806 |         QualType ConvType = Conv->getConversionType().getNonReferenceType(); | 
 | 1807 |         if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>()) | 
| Eli Friedman | 1357869 | 2010-08-05 02:49:48 +0000 | [diff] [blame] | 1808 |           if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType()) | 
| Fariborz Jahanian | 8b915e7 | 2009-09-15 22:15:23 +0000 | [diff] [blame] | 1809 |             ObjectPtrConversions.push_back(Conv); | 
| Douglas Gregor | 9cd9f3f | 2009-09-09 23:39:55 +0000 | [diff] [blame] | 1810 |       } | 
| Fariborz Jahanian | 8b915e7 | 2009-09-15 22:15:23 +0000 | [diff] [blame] | 1811 |       if (ObjectPtrConversions.size() == 1) { | 
 | 1812 |         // We have a single conversion to a pointer-to-object type. Perform | 
 | 1813 |         // that conversion. | 
| John McCall | 32daa42 | 2010-03-31 01:36:47 +0000 | [diff] [blame] | 1814 |         // TODO: don't redo the conversion calculation. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1815 |         ExprResult Res = | 
 | 1816 |           PerformImplicitConversion(Ex.get(), | 
| John McCall | 32daa42 | 2010-03-31 01:36:47 +0000 | [diff] [blame] | 1817 |                             ObjectPtrConversions.front()->getConversionType(), | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1818 |                                     AA_Converting); | 
 | 1819 |         if (Res.isUsable()) { | 
 | 1820 |           Ex = move(Res); | 
 | 1821 |           Type = Ex.get()->getType(); | 
| Fariborz Jahanian | 8b915e7 | 2009-09-15 22:15:23 +0000 | [diff] [blame] | 1822 |         } | 
 | 1823 |       } | 
 | 1824 |       else if (ObjectPtrConversions.size() > 1) { | 
 | 1825 |         Diag(StartLoc, diag::err_ambiguous_delete_operand) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1826 |               << Type << Ex.get()->getSourceRange(); | 
| John McCall | 32daa42 | 2010-03-31 01:36:47 +0000 | [diff] [blame] | 1827 |         for (unsigned i= 0; i < ObjectPtrConversions.size(); i++) | 
 | 1828 |           NoteOverloadCandidate(ObjectPtrConversions[i]); | 
| Fariborz Jahanian | 8b915e7 | 2009-09-15 22:15:23 +0000 | [diff] [blame] | 1829 |         return ExprError(); | 
| Douglas Gregor | 9cd9f3f | 2009-09-09 23:39:55 +0000 | [diff] [blame] | 1830 |       } | 
| Sebastian Redl | 2850784 | 2009-02-26 14:39:58 +0000 | [diff] [blame] | 1831 |     } | 
 | 1832 |  | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 1833 |     if (!Type->isPointerType()) | 
 | 1834 |       return ExprError(Diag(StartLoc, diag::err_delete_operand) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1835 |         << Type << Ex.get()->getSourceRange()); | 
| Sebastian Redl | 2850784 | 2009-02-26 14:39:58 +0000 | [diff] [blame] | 1836 |  | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 1837 |     QualType Pointee = Type->getAs<PointerType>()->getPointeeType(); | 
| Eli Friedman | e52c914 | 2011-07-26 22:25:31 +0000 | [diff] [blame] | 1838 |     QualType PointeeElem = Context.getBaseElementType(Pointee); | 
 | 1839 |  | 
 | 1840 |     if (unsigned AddressSpace = Pointee.getAddressSpace()) | 
 | 1841 |       return Diag(Ex.get()->getLocStart(),  | 
 | 1842 |                   diag::err_address_space_qualified_delete) | 
 | 1843 |                << Pointee.getUnqualifiedType() << AddressSpace; | 
 | 1844 |  | 
 | 1845 |     CXXRecordDecl *PointeeRD = 0; | 
| Douglas Gregor | 94a6157 | 2010-05-24 17:01:56 +0000 | [diff] [blame] | 1846 |     if (Pointee->isVoidType() && !isSFINAEContext()) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1847 |       // The C++ standard bans deleting a pointer to a non-object type, which | 
| Douglas Gregor | 94a6157 | 2010-05-24 17:01:56 +0000 | [diff] [blame] | 1848 |       // effectively bans deletion of "void*". However, most compilers support | 
 | 1849 |       // this, so we treat it as a warning unless we're in a SFINAE context. | 
 | 1850 |       Diag(StartLoc, diag::ext_delete_void_ptr_operand) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1851 |         << Type << Ex.get()->getSourceRange(); | 
| Eli Friedman | e52c914 | 2011-07-26 22:25:31 +0000 | [diff] [blame] | 1852 |     } else if (Pointee->isFunctionType() || Pointee->isVoidType()) { | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 1853 |       return ExprError(Diag(StartLoc, diag::err_delete_operand) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1854 |         << Type << Ex.get()->getSourceRange()); | 
| Eli Friedman | e52c914 | 2011-07-26 22:25:31 +0000 | [diff] [blame] | 1855 |     } else if (!Pointee->isDependentType()) { | 
 | 1856 |       if (!RequireCompleteType(StartLoc, Pointee, | 
 | 1857 |                                PDiag(diag::warn_delete_incomplete) | 
 | 1858 |                                  << Ex.get()->getSourceRange())) { | 
 | 1859 |         if (const RecordType *RT = PointeeElem->getAs<RecordType>()) | 
 | 1860 |           PointeeRD = cast<CXXRecordDecl>(RT->getDecl()); | 
 | 1861 |       } | 
 | 1862 |     } | 
 | 1863 |  | 
| Douglas Gregor | 1070c9f | 2009-09-29 21:38:53 +0000 | [diff] [blame] | 1864 |     // C++ [expr.delete]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1865 |     //   [Note: a pointer to a const type can be the operand of a | 
 | 1866 |     //   delete-expression; it is not necessary to cast away the constness | 
 | 1867 |     //   (5.2.11) of the pointer expression before it is used as the operand | 
| Douglas Gregor | 1070c9f | 2009-09-29 21:38:53 +0000 | [diff] [blame] | 1868 |     //   of the delete-expression. ] | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 1869 |     if (!Context.hasSameType(Ex.get()->getType(), Context.VoidPtrTy)) | 
 | 1870 |       Ex = Owned(ImplicitCastExpr::Create(Context, Context.VoidPtrTy, CK_NoOp, | 
 | 1871 |                                           Ex.take(), 0, VK_RValue)); | 
| Argyrios Kyrtzidis | 4076dac | 2010-09-13 20:15:54 +0000 | [diff] [blame] | 1872 |  | 
 | 1873 |     if (Pointee->isArrayType() && !ArrayForm) { | 
 | 1874 |       Diag(StartLoc, diag::warn_delete_array_type) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1875 |           << Type << Ex.get()->getSourceRange() | 
| Argyrios Kyrtzidis | 4076dac | 2010-09-13 20:15:54 +0000 | [diff] [blame] | 1876 |           << FixItHint::CreateInsertion(PP.getLocForEndOfToken(StartLoc), "[]"); | 
 | 1877 |       ArrayForm = true; | 
 | 1878 |     } | 
 | 1879 |  | 
| Anders Carlsson | d67c4c3 | 2009-08-16 20:29:29 +0000 | [diff] [blame] | 1880 |     DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName( | 
 | 1881 |                                       ArrayForm ? OO_Array_Delete : OO_Delete); | 
 | 1882 |  | 
| Eli Friedman | e52c914 | 2011-07-26 22:25:31 +0000 | [diff] [blame] | 1883 |     if (PointeeRD) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1884 |       if (!UseGlobal && | 
| Eli Friedman | e52c914 | 2011-07-26 22:25:31 +0000 | [diff] [blame] | 1885 |           FindDeallocationFunction(StartLoc, PointeeRD, DeleteName, | 
 | 1886 |                                    OperatorDelete)) | 
| Anders Carlsson | 0ba63ea | 2009-11-14 03:17:38 +0000 | [diff] [blame] | 1887 |         return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1888 |  | 
| John McCall | 6ec278d | 2011-01-27 09:37:56 +0000 | [diff] [blame] | 1889 |       // If we're allocating an array of records, check whether the | 
 | 1890 |       // usual operator delete[] has a size_t parameter. | 
 | 1891 |       if (ArrayForm) { | 
 | 1892 |         // If the user specifically asked to use the global allocator, | 
 | 1893 |         // we'll need to do the lookup into the class. | 
 | 1894 |         if (UseGlobal) | 
 | 1895 |           UsualArrayDeleteWantsSize = | 
 | 1896 |             doesUsualArrayDeleteWantSize(*this, StartLoc, PointeeElem); | 
 | 1897 |  | 
 | 1898 |         // Otherwise, the usual operator delete[] should be the | 
 | 1899 |         // function we just found. | 
 | 1900 |         else if (isa<CXXMethodDecl>(OperatorDelete)) | 
 | 1901 |           UsualArrayDeleteWantsSize = (OperatorDelete->getNumParams() == 2); | 
 | 1902 |       } | 
 | 1903 |  | 
| Eli Friedman | e52c914 | 2011-07-26 22:25:31 +0000 | [diff] [blame] | 1904 |       if (!PointeeRD->hasTrivialDestructor()) | 
 | 1905 |         if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1906 |           MarkDeclarationReferenced(StartLoc, | 
| Fariborz Jahanian | 34374e6 | 2009-09-03 23:18:17 +0000 | [diff] [blame] | 1907 |                                     const_cast<CXXDestructorDecl*>(Dtor)); | 
| Douglas Gregor | 9b62363 | 2010-10-12 23:32:35 +0000 | [diff] [blame] | 1908 |           DiagnoseUseOfDecl(Dtor, StartLoc); | 
 | 1909 |         } | 
| Argyrios Kyrtzidis | 6f0074a | 2011-05-24 19:53:26 +0000 | [diff] [blame] | 1910 |  | 
 | 1911 |       // C++ [expr.delete]p3: | 
 | 1912 |       //   In the first alternative (delete object), if the static type of the | 
 | 1913 |       //   object to be deleted is different from its dynamic type, the static | 
 | 1914 |       //   type shall be a base class of the dynamic type of the object to be | 
 | 1915 |       //   deleted and the static type shall have a virtual destructor or the | 
 | 1916 |       //   behavior is undefined. | 
 | 1917 |       // | 
 | 1918 |       // Note: a final class cannot be derived from, no issue there | 
| Eli Friedman | ef8c79c | 2011-07-26 23:27:24 +0000 | [diff] [blame] | 1919 |       if (PointeeRD->isPolymorphic() && !PointeeRD->hasAttr<FinalAttr>()) { | 
| Eli Friedman | e52c914 | 2011-07-26 22:25:31 +0000 | [diff] [blame] | 1920 |         CXXDestructorDecl *dtor = PointeeRD->getDestructor(); | 
| Eli Friedman | ef8c79c | 2011-07-26 23:27:24 +0000 | [diff] [blame] | 1921 |         if (dtor && !dtor->isVirtual()) { | 
 | 1922 |           if (PointeeRD->isAbstract()) { | 
 | 1923 |             // If the class is abstract, we warn by default, because we're | 
 | 1924 |             // sure the code has undefined behavior. | 
 | 1925 |             Diag(StartLoc, diag::warn_delete_abstract_non_virtual_dtor) | 
 | 1926 |                 << PointeeElem; | 
 | 1927 |           } else if (!ArrayForm) { | 
 | 1928 |             // Otherwise, if this is not an array delete, it's a bit suspect, | 
 | 1929 |             // but not necessarily wrong. | 
 | 1930 |             Diag(StartLoc, diag::warn_delete_non_virtual_dtor) << PointeeElem; | 
 | 1931 |           } | 
 | 1932 |         } | 
| Argyrios Kyrtzidis | 6f0074a | 2011-05-24 19:53:26 +0000 | [diff] [blame] | 1933 |       } | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 1934 |  | 
 | 1935 |     } else if (getLangOptions().ObjCAutoRefCount && | 
 | 1936 |                PointeeElem->isObjCLifetimeType() && | 
 | 1937 |                (PointeeElem.getObjCLifetime() == Qualifiers::OCL_Strong || | 
 | 1938 |                 PointeeElem.getObjCLifetime() == Qualifiers::OCL_Weak) && | 
 | 1939 |                ArrayForm) { | 
 | 1940 |       Diag(StartLoc, diag::warn_err_new_delete_object_array) | 
 | 1941 |         << 1 << PointeeElem; | 
| Anders Carlsson | d67c4c3 | 2009-08-16 20:29:29 +0000 | [diff] [blame] | 1942 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1943 |  | 
| Anders Carlsson | d67c4c3 | 2009-08-16 20:29:29 +0000 | [diff] [blame] | 1944 |     if (!OperatorDelete) { | 
| Anders Carlsson | 78f7455 | 2009-11-15 18:45:20 +0000 | [diff] [blame] | 1945 |       // Look for a global declaration. | 
| Anders Carlsson | d67c4c3 | 2009-08-16 20:29:29 +0000 | [diff] [blame] | 1946 |       DeclareGlobalNewDelete(); | 
 | 1947 |       DeclContext *TUDecl = Context.getTranslationUnitDecl(); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1948 |       Expr *Arg = Ex.get(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1949 |       if (FindAllocationOverload(StartLoc, SourceRange(), DeleteName, | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1950 |                                  &Arg, 1, TUDecl, /*AllowMissing=*/false, | 
| Anders Carlsson | d67c4c3 | 2009-08-16 20:29:29 +0000 | [diff] [blame] | 1951 |                                  OperatorDelete)) | 
 | 1952 |         return ExprError(); | 
 | 1953 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1954 |  | 
| John McCall | 9c82afc | 2010-04-20 02:18:25 +0000 | [diff] [blame] | 1955 |     MarkDeclarationReferenced(StartLoc, OperatorDelete); | 
| John McCall | 6ec278d | 2011-01-27 09:37:56 +0000 | [diff] [blame] | 1956 |      | 
| Douglas Gregor | d880f52 | 2011-02-01 15:50:11 +0000 | [diff] [blame] | 1957 |     // Check access and ambiguity of operator delete and destructor. | 
| Eli Friedman | e52c914 | 2011-07-26 22:25:31 +0000 | [diff] [blame] | 1958 |     if (PointeeRD) { | 
 | 1959 |       if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1960 |           CheckDestructorAccess(Ex.get()->getExprLoc(), Dtor,  | 
| Douglas Gregor | d880f52 | 2011-02-01 15:50:11 +0000 | [diff] [blame] | 1961 |                       PDiag(diag::err_access_dtor) << PointeeElem); | 
 | 1962 |       } | 
 | 1963 |     } | 
 | 1964 |  | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1965 |   } | 
 | 1966 |  | 
| Sebastian Redl | f53597f | 2009-03-15 17:47:39 +0000 | [diff] [blame] | 1967 |   return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm, | 
| John McCall | 6ec278d | 2011-01-27 09:37:56 +0000 | [diff] [blame] | 1968 |                                            ArrayFormAsWritten, | 
 | 1969 |                                            UsualArrayDeleteWantsSize, | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1970 |                                            OperatorDelete, Ex.take(), StartLoc)); | 
| Sebastian Redl | 4c5d320 | 2008-11-21 19:14:01 +0000 | [diff] [blame] | 1971 | } | 
 | 1972 |  | 
| Douglas Gregor | 8cfe5a7 | 2009-11-23 23:44:04 +0000 | [diff] [blame] | 1973 | /// \brief Check the use of the given variable as a C++ condition in an if, | 
 | 1974 | /// while, do-while, or switch statement. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 1975 | ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 1976 |                                         SourceLocation StmtLoc, | 
 | 1977 |                                         bool ConvertToBoolean) { | 
| Douglas Gregor | 8cfe5a7 | 2009-11-23 23:44:04 +0000 | [diff] [blame] | 1978 |   QualType T = ConditionVar->getType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1979 |  | 
| Douglas Gregor | 8cfe5a7 | 2009-11-23 23:44:04 +0000 | [diff] [blame] | 1980 |   // C++ [stmt.select]p2: | 
 | 1981 |   //   The declarator shall not specify a function or an array. | 
 | 1982 |   if (T->isFunctionType()) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1983 |     return ExprError(Diag(ConditionVar->getLocation(), | 
| Douglas Gregor | 8cfe5a7 | 2009-11-23 23:44:04 +0000 | [diff] [blame] | 1984 |                           diag::err_invalid_use_of_function_type) | 
 | 1985 |                        << ConditionVar->getSourceRange()); | 
 | 1986 |   else if (T->isArrayType()) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1987 |     return ExprError(Diag(ConditionVar->getLocation(), | 
| Douglas Gregor | 8cfe5a7 | 2009-11-23 23:44:04 +0000 | [diff] [blame] | 1988 |                           diag::err_invalid_use_of_array_type) | 
 | 1989 |                      << ConditionVar->getSourceRange()); | 
| Douglas Gregor | a7605db | 2009-11-24 16:07:02 +0000 | [diff] [blame] | 1990 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1991 |   ExprResult Condition = | 
 | 1992 |     Owned(DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),  | 
| Douglas Gregor | 40d96a6 | 2011-02-28 21:54:11 +0000 | [diff] [blame] | 1993 |                                         ConditionVar, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1994 |                                         ConditionVar->getLocation(), | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 1995 |                             ConditionVar->getType().getNonReferenceType(), | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 1996 |                               VK_LValue)); | 
 | 1997 |   if (ConvertToBoolean) { | 
 | 1998 |     Condition = CheckBooleanCondition(Condition.take(), StmtLoc); | 
 | 1999 |     if (Condition.isInvalid()) | 
 | 2000 |       return ExprError(); | 
 | 2001 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2002 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2003 |   return move(Condition); | 
| Douglas Gregor | 8cfe5a7 | 2009-11-23 23:44:04 +0000 | [diff] [blame] | 2004 | } | 
 | 2005 |  | 
| Argyrios Kyrtzidis | 5921093 | 2008-09-10 02:17:11 +0000 | [diff] [blame] | 2006 | /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2007 | ExprResult Sema::CheckCXXBooleanCondition(Expr *CondExpr) { | 
| Argyrios Kyrtzidis | 5921093 | 2008-09-10 02:17:11 +0000 | [diff] [blame] | 2008 |   // C++ 6.4p4: | 
 | 2009 |   // The value of a condition that is an initialized declaration in a statement | 
 | 2010 |   // other than a switch statement is the value of the declared variable | 
 | 2011 |   // implicitly converted to type bool. If that conversion is ill-formed, the | 
 | 2012 |   // program is ill-formed. | 
 | 2013 |   // The value of a condition that is an expression is the value of the | 
 | 2014 |   // expression, implicitly converted to bool. | 
 | 2015 |   // | 
| Douglas Gregor | 09f41cf | 2009-01-14 15:45:31 +0000 | [diff] [blame] | 2016 |   return PerformContextuallyConvertToBool(CondExpr); | 
| Argyrios Kyrtzidis | 5921093 | 2008-09-10 02:17:11 +0000 | [diff] [blame] | 2017 | } | 
| Douglas Gregor | 77a5223 | 2008-09-12 00:47:35 +0000 | [diff] [blame] | 2018 |  | 
 | 2019 | /// Helper function to determine whether this is the (deprecated) C++ | 
 | 2020 | /// conversion from a string literal to a pointer to non-const char or | 
 | 2021 | /// non-const wchar_t (for narrow and wide string literals, | 
 | 2022 | /// respectively). | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2023 | bool | 
| Douglas Gregor | 77a5223 | 2008-09-12 00:47:35 +0000 | [diff] [blame] | 2024 | Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) { | 
 | 2025 |   // Look inside the implicit cast, if it exists. | 
 | 2026 |   if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(From)) | 
 | 2027 |     From = Cast->getSubExpr(); | 
 | 2028 |  | 
 | 2029 |   // A string literal (2.13.4) that is not a wide string literal can | 
 | 2030 |   // be converted to an rvalue of type "pointer to char"; a wide | 
 | 2031 |   // string literal can be converted to an rvalue of type "pointer | 
 | 2032 |   // to wchar_t" (C++ 4.2p2). | 
| Douglas Gregor | 1984eb9 | 2010-06-22 23:47:37 +0000 | [diff] [blame] | 2033 |   if (StringLiteral *StrLit = dyn_cast<StringLiteral>(From->IgnoreParens())) | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 2034 |     if (const PointerType *ToPtrType = ToType->getAs<PointerType>()) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2035 |       if (const BuiltinType *ToPointeeType | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 2036 |           = ToPtrType->getPointeeType()->getAs<BuiltinType>()) { | 
| Douglas Gregor | 77a5223 | 2008-09-12 00:47:35 +0000 | [diff] [blame] | 2037 |         // This conversion is considered only when there is an | 
 | 2038 |         // explicit appropriate pointer target type (C++ 4.2p2). | 
| Douglas Gregor | 5cee119 | 2011-07-27 05:40:30 +0000 | [diff] [blame] | 2039 |         if (!ToPtrType->getPointeeType().hasQualifiers()) { | 
 | 2040 |           switch (StrLit->getKind()) { | 
 | 2041 |             case StringLiteral::UTF8: | 
 | 2042 |             case StringLiteral::UTF16: | 
 | 2043 |             case StringLiteral::UTF32: | 
 | 2044 |               // We don't allow UTF literals to be implicitly converted | 
 | 2045 |               break; | 
 | 2046 |             case StringLiteral::Ascii: | 
 | 2047 |               return (ToPointeeType->getKind() == BuiltinType::Char_U || | 
 | 2048 |                       ToPointeeType->getKind() == BuiltinType::Char_S); | 
 | 2049 |             case StringLiteral::Wide: | 
 | 2050 |               return ToPointeeType->isWideCharType(); | 
 | 2051 |           } | 
 | 2052 |         } | 
| Douglas Gregor | 77a5223 | 2008-09-12 00:47:35 +0000 | [diff] [blame] | 2053 |       } | 
 | 2054 |  | 
 | 2055 |   return false; | 
 | 2056 | } | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2057 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2058 | static ExprResult BuildCXXCastArgument(Sema &S, | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2059 |                                        SourceLocation CastLoc, | 
 | 2060 |                                        QualType Ty, | 
 | 2061 |                                        CastKind Kind, | 
 | 2062 |                                        CXXMethodDecl *Method, | 
| John McCall | ca82a82 | 2011-09-21 08:36:56 +0000 | [diff] [blame] | 2063 |                                        DeclAccessPair FoundDecl, | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 2064 |                                        bool HadMultipleCandidates, | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2065 |                                        Expr *From) { | 
| Douglas Gregor | ba70ab6 | 2010-04-16 22:17:36 +0000 | [diff] [blame] | 2066 |   switch (Kind) { | 
| David Blaikie | b219cfc | 2011-09-23 05:06:16 +0000 | [diff] [blame] | 2067 |   default: llvm_unreachable("Unhandled cast kind!"); | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2068 |   case CK_ConstructorConversion: { | 
| Douglas Gregor | 13e1bca | 2011-10-10 22:41:00 +0000 | [diff] [blame] | 2069 |     CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Method); | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 2070 |     ASTOwningVector<Expr*> ConstructorArgs(S); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2071 |  | 
| Douglas Gregor | 13e1bca | 2011-10-10 22:41:00 +0000 | [diff] [blame] | 2072 |     if (S.CompleteConstructorCall(Constructor, | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 2073 |                                   MultiExprArg(&From, 1), | 
| Douglas Gregor | ba70ab6 | 2010-04-16 22:17:36 +0000 | [diff] [blame] | 2074 |                                   CastLoc, ConstructorArgs)) | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 2075 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2076 |  | 
| Douglas Gregor | 13e1bca | 2011-10-10 22:41:00 +0000 | [diff] [blame] | 2077 |     S.CheckConstructorAccess(CastLoc, Constructor, Constructor->getAccess(), | 
 | 2078 |                              S.PDiag(diag::err_access_ctor)); | 
 | 2079 |      | 
 | 2080 |     ExprResult Result | 
 | 2081 |       = S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method), | 
 | 2082 |                                 move_arg(ConstructorArgs),  | 
 | 2083 |                                 HadMultipleCandidates, /*ZeroInit*/ false,  | 
 | 2084 |                                 CXXConstructExpr::CK_Complete, SourceRange()); | 
| Douglas Gregor | ba70ab6 | 2010-04-16 22:17:36 +0000 | [diff] [blame] | 2085 |     if (Result.isInvalid()) | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 2086 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2087 |  | 
| Douglas Gregor | ba70ab6 | 2010-04-16 22:17:36 +0000 | [diff] [blame] | 2088 |     return S.MaybeBindToTemporary(Result.takeAs<Expr>()); | 
 | 2089 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2090 |  | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2091 |   case CK_UserDefinedConversion: { | 
| Douglas Gregor | ba70ab6 | 2010-04-16 22:17:36 +0000 | [diff] [blame] | 2092 |     assert(!From->getType()->isPointerType() && "Arg can't have pointer type!"); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2093 |  | 
| Douglas Gregor | ba70ab6 | 2010-04-16 22:17:36 +0000 | [diff] [blame] | 2094 |     // Create an implicit call expr that calls it. | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 2095 |     ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Method, | 
 | 2096 |                                                  HadMultipleCandidates); | 
| Douglas Gregor | f2ae526 | 2011-01-20 00:18:04 +0000 | [diff] [blame] | 2097 |     if (Result.isInvalid()) | 
 | 2098 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2099 |  | 
| John McCall | ca82a82 | 2011-09-21 08:36:56 +0000 | [diff] [blame] | 2100 |     S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ 0, FoundDecl); | 
 | 2101 |  | 
| Douglas Gregor | f2ae526 | 2011-01-20 00:18:04 +0000 | [diff] [blame] | 2102 |     return S.MaybeBindToTemporary(Result.get()); | 
| Douglas Gregor | ba70ab6 | 2010-04-16 22:17:36 +0000 | [diff] [blame] | 2103 |   } | 
 | 2104 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2105 | } | 
| Douglas Gregor | ba70ab6 | 2010-04-16 22:17:36 +0000 | [diff] [blame] | 2106 |  | 
| Douglas Gregor | 09f41cf | 2009-01-14 15:45:31 +0000 | [diff] [blame] | 2107 | /// PerformImplicitConversion - Perform an implicit conversion of the | 
 | 2108 | /// expression From to the type ToType using the pre-computed implicit | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2109 | /// conversion sequence ICS. Returns the converted | 
| Douglas Gregor | 6864748 | 2009-12-16 03:45:30 +0000 | [diff] [blame] | 2110 | /// expression. Action is the kind of conversion we're performing, | 
| Douglas Gregor | 09f41cf | 2009-01-14 15:45:31 +0000 | [diff] [blame] | 2111 | /// used in the error message. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2112 | ExprResult | 
 | 2113 | Sema::PerformImplicitConversion(Expr *From, QualType ToType, | 
| Douglas Gregor | 09f41cf | 2009-01-14 15:45:31 +0000 | [diff] [blame] | 2114 |                                 const ImplicitConversionSequence &ICS, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2115 |                                 AssignmentAction Action,  | 
 | 2116 |                                 CheckedConversionKind CCK) { | 
| John McCall | 1d31833 | 2010-01-12 00:44:57 +0000 | [diff] [blame] | 2117 |   switch (ICS.getKind()) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2118 |   case ImplicitConversionSequence::StandardConversion: { | 
 | 2119 |     ExprResult Res = PerformImplicitConversion(From, ToType, ICS.Standard, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2120 |                                                Action, CCK); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2121 |     if (Res.isInvalid()) | 
 | 2122 |       return ExprError(); | 
 | 2123 |     From = Res.take(); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2124 |     break; | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2125 |   } | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2126 |  | 
| Anders Carlsson | f6c213a | 2009-09-15 06:28:28 +0000 | [diff] [blame] | 2127 |   case ImplicitConversionSequence::UserDefinedConversion: { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2128 |  | 
| Fariborz Jahanian | 7fe5d72 | 2009-08-28 22:04:50 +0000 | [diff] [blame] | 2129 |       FunctionDecl *FD = ICS.UserDefined.ConversionFunction; | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2130 |       CastKind CastKind; | 
| Anders Carlsson | f6c213a | 2009-09-15 06:28:28 +0000 | [diff] [blame] | 2131 |       QualType BeforeToType; | 
| Sebastian Redl | cc7a648 | 2011-11-01 15:53:09 +0000 | [diff] [blame^] | 2132 |       assert(FD && "FIXME: aggregate initialization from init list"); | 
| Anders Carlsson | f6c213a | 2009-09-15 06:28:28 +0000 | [diff] [blame] | 2133 |       if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) { | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2134 |         CastKind = CK_UserDefinedConversion; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2135 |  | 
| Anders Carlsson | f6c213a | 2009-09-15 06:28:28 +0000 | [diff] [blame] | 2136 |         // If the user-defined conversion is specified by a conversion function, | 
 | 2137 |         // the initial standard conversion sequence converts the source type to | 
 | 2138 |         // the implicit object parameter of the conversion function. | 
 | 2139 |         BeforeToType = Context.getTagDeclType(Conv->getParent()); | 
| John McCall | 9ec9445 | 2010-12-04 09:57:16 +0000 | [diff] [blame] | 2140 |       } else { | 
 | 2141 |         const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(FD); | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2142 |         CastKind = CK_ConstructorConversion; | 
| Fariborz Jahanian | 966256a | 2009-11-06 00:23:08 +0000 | [diff] [blame] | 2143 |         // Do no conversion if dealing with ... for the first conversion. | 
| Douglas Gregor | e44201a | 2009-11-20 02:31:03 +0000 | [diff] [blame] | 2144 |         if (!ICS.UserDefined.EllipsisConversion) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2145 |           // If the user-defined conversion is specified by a constructor, the | 
| Fariborz Jahanian | 966256a | 2009-11-06 00:23:08 +0000 | [diff] [blame] | 2146 |           // initial standard conversion sequence converts the source type to the | 
 | 2147 |           // type required by the argument of the constructor | 
| Douglas Gregor | e44201a | 2009-11-20 02:31:03 +0000 | [diff] [blame] | 2148 |           BeforeToType = Ctor->getParamDecl(0)->getType().getNonReferenceType(); | 
 | 2149 |         } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2150 |       } | 
| Douglas Gregor | a3998bd | 2010-12-02 21:47:04 +0000 | [diff] [blame] | 2151 |       // Watch out for elipsis conversion. | 
| Fariborz Jahanian | 4c0cea2 | 2009-11-06 00:55:14 +0000 | [diff] [blame] | 2152 |       if (!ICS.UserDefined.EllipsisConversion) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2153 |         ExprResult Res = | 
 | 2154 |           PerformImplicitConversion(From, BeforeToType, | 
 | 2155 |                                     ICS.UserDefined.Before, AA_Converting, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2156 |                                     CCK); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2157 |         if (Res.isInvalid()) | 
 | 2158 |           return ExprError(); | 
 | 2159 |         From = Res.take(); | 
| Fariborz Jahanian | 966256a | 2009-11-06 00:23:08 +0000 | [diff] [blame] | 2160 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2161 |  | 
 | 2162 |       ExprResult CastArg | 
| Douglas Gregor | ba70ab6 | 2010-04-16 22:17:36 +0000 | [diff] [blame] | 2163 |         = BuildCXXCastArgument(*this, | 
 | 2164 |                                From->getLocStart(), | 
| Anders Carlsson | 0aebc81 | 2009-09-09 21:33:21 +0000 | [diff] [blame] | 2165 |                                ToType.getNonReferenceType(), | 
| Douglas Gregor | 83eecbe | 2011-01-20 01:32:05 +0000 | [diff] [blame] | 2166 |                                CastKind, cast<CXXMethodDecl>(FD), | 
 | 2167 |                                ICS.UserDefined.FoundConversionFunction, | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 2168 |                                ICS.UserDefined.HadMultipleCandidates, | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 2169 |                                From); | 
| Anders Carlsson | 0aebc81 | 2009-09-09 21:33:21 +0000 | [diff] [blame] | 2170 |  | 
 | 2171 |       if (CastArg.isInvalid()) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2172 |         return ExprError(); | 
| Eli Friedman | d888962 | 2009-11-27 04:41:50 +0000 | [diff] [blame] | 2173 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2174 |       From = CastArg.take(); | 
| Eli Friedman | d888962 | 2009-11-27 04:41:50 +0000 | [diff] [blame] | 2175 |  | 
| Eli Friedman | d888962 | 2009-11-27 04:41:50 +0000 | [diff] [blame] | 2176 |       return PerformImplicitConversion(From, ToType, ICS.UserDefined.After, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2177 |                                        AA_Converting, CCK); | 
| Fariborz Jahanian | 93034ca | 2009-10-16 19:20:59 +0000 | [diff] [blame] | 2178 |   } | 
| John McCall | 1d31833 | 2010-01-12 00:44:57 +0000 | [diff] [blame] | 2179 |  | 
 | 2180 |   case ImplicitConversionSequence::AmbiguousConversion: | 
| John McCall | 120d63c | 2010-08-24 20:38:10 +0000 | [diff] [blame] | 2181 |     ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(), | 
| John McCall | 1d31833 | 2010-01-12 00:44:57 +0000 | [diff] [blame] | 2182 |                           PDiag(diag::err_typecheck_ambiguous_condition) | 
 | 2183 |                             << From->getSourceRange()); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2184 |      return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2185 |  | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2186 |   case ImplicitConversionSequence::EllipsisConversion: | 
| David Blaikie | b219cfc | 2011-09-23 05:06:16 +0000 | [diff] [blame] | 2187 |     llvm_unreachable("Cannot perform an ellipsis conversion"); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2188 |  | 
 | 2189 |   case ImplicitConversionSequence::BadConversion: | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2190 |     return ExprError(); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2191 |   } | 
 | 2192 |  | 
 | 2193 |   // Everything went well. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2194 |   return Owned(From); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2195 | } | 
 | 2196 |  | 
 | 2197 | /// PerformImplicitConversion - Perform an implicit conversion of the | 
 | 2198 | /// expression From to the type ToType by following the standard | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2199 | /// conversion sequence SCS. Returns the converted | 
| Douglas Gregor | 45920e8 | 2008-12-19 17:40:08 +0000 | [diff] [blame] | 2200 | /// expression. Flavor is the context in which we're performing this | 
 | 2201 | /// conversion, for use in error messages. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2202 | ExprResult | 
 | 2203 | Sema::PerformImplicitConversion(Expr *From, QualType ToType, | 
| Douglas Gregor | 45920e8 | 2008-12-19 17:40:08 +0000 | [diff] [blame] | 2204 |                                 const StandardConversionSequence& SCS, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2205 |                                 AssignmentAction Action,  | 
 | 2206 |                                 CheckedConversionKind CCK) { | 
 | 2207 |   bool CStyle = (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast); | 
 | 2208 |    | 
| Mike Stump | 390b4cc | 2009-05-16 07:39:55 +0000 | [diff] [blame] | 2209 |   // Overall FIXME: we are recomputing too many types here and doing far too | 
 | 2210 |   // much extra work. What this means is that we need to keep track of more | 
 | 2211 |   // information that is computed when we try the implicit conversion initially, | 
 | 2212 |   // so that we don't need to recompute anything here. | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2213 |   QualType FromType = From->getType(); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2214 |    | 
| Douglas Gregor | 225c41e | 2008-11-03 19:09:14 +0000 | [diff] [blame] | 2215 |   if (SCS.CopyConstructor) { | 
| Anders Carlsson | 7c3e8a1 | 2009-05-19 04:45:15 +0000 | [diff] [blame] | 2216 |     // FIXME: When can ToType be a reference type? | 
 | 2217 |     assert(!ToType->isReferenceType()); | 
| Fariborz Jahanian | b3c4774 | 2009-09-25 18:59:21 +0000 | [diff] [blame] | 2218 |     if (SCS.Second == ICK_Derived_To_Base) { | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 2219 |       ASTOwningVector<Expr*> ConstructorArgs(*this); | 
| Fariborz Jahanian | b3c4774 | 2009-09-25 18:59:21 +0000 | [diff] [blame] | 2220 |       if (CompleteConstructorCall(cast<CXXConstructorDecl>(SCS.CopyConstructor), | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 2221 |                                   MultiExprArg(*this, &From, 1), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2222 |                                   /*FIXME:ConstructLoc*/SourceLocation(), | 
| Fariborz Jahanian | b3c4774 | 2009-09-25 18:59:21 +0000 | [diff] [blame] | 2223 |                                   ConstructorArgs)) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2224 |         return ExprError(); | 
 | 2225 |       return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(), | 
 | 2226 |                                    ToType, SCS.CopyConstructor, | 
 | 2227 |                                    move_arg(ConstructorArgs), | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 2228 |                                    /*HadMultipleCandidates*/ false, | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2229 |                                    /*ZeroInit*/ false, | 
 | 2230 |                                    CXXConstructExpr::CK_Complete, | 
 | 2231 |                                    SourceRange()); | 
| Fariborz Jahanian | b3c4774 | 2009-09-25 18:59:21 +0000 | [diff] [blame] | 2232 |     } | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2233 |     return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(), | 
 | 2234 |                                  ToType, SCS.CopyConstructor, | 
 | 2235 |                                  MultiExprArg(*this, &From, 1), | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 2236 |                                  /*HadMultipleCandidates*/ false, | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2237 |                                  /*ZeroInit*/ false, | 
 | 2238 |                                  CXXConstructExpr::CK_Complete, | 
 | 2239 |                                  SourceRange()); | 
| Douglas Gregor | 225c41e | 2008-11-03 19:09:14 +0000 | [diff] [blame] | 2240 |   } | 
 | 2241 |  | 
| Douglas Gregor | ad4e02f | 2010-04-29 18:24:40 +0000 | [diff] [blame] | 2242 |   // Resolve overloaded function references. | 
 | 2243 |   if (Context.hasSameType(FromType, Context.OverloadTy)) { | 
 | 2244 |     DeclAccessPair Found; | 
 | 2245 |     FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType, | 
 | 2246 |                                                           true, Found); | 
 | 2247 |     if (!Fn) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2248 |       return ExprError(); | 
| Douglas Gregor | ad4e02f | 2010-04-29 18:24:40 +0000 | [diff] [blame] | 2249 |  | 
 | 2250 |     if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin())) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2251 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2252 |  | 
| Douglas Gregor | ad4e02f | 2010-04-29 18:24:40 +0000 | [diff] [blame] | 2253 |     From = FixOverloadedFunctionReference(From, Found, Fn); | 
 | 2254 |     FromType = From->getType(); | 
 | 2255 |   } | 
 | 2256 |  | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2257 |   // Perform the first implicit conversion. | 
 | 2258 |   switch (SCS.First) { | 
 | 2259 |   case ICK_Identity: | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2260 |     // Nothing to do. | 
 | 2261 |     break; | 
 | 2262 |  | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 2263 |   case ICK_Lvalue_To_Rvalue: | 
| John McCall | 3c3b7f9 | 2011-10-25 17:37:35 +0000 | [diff] [blame] | 2264 |     assert(From->getObjectKind() != OK_ObjCProperty); | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 2265 |     FromType = FromType.getUnqualifiedType(); | 
 | 2266 |     From = ImplicitCastExpr::Create(Context, FromType, CK_LValueToRValue, | 
 | 2267 |                                     From, 0, VK_RValue); | 
 | 2268 |     break; | 
 | 2269 |  | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2270 |   case ICK_Array_To_Pointer: | 
| Douglas Gregor | 48f3bb9 | 2009-02-18 21:56:37 +0000 | [diff] [blame] | 2271 |     FromType = Context.getArrayDecayedType(FromType); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2272 |     From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay,  | 
 | 2273 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Douglas Gregor | 48f3bb9 | 2009-02-18 21:56:37 +0000 | [diff] [blame] | 2274 |     break; | 
 | 2275 |  | 
 | 2276 |   case ICK_Function_To_Pointer: | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2277 |     FromType = Context.getPointerType(FromType); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2278 |     From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay,  | 
 | 2279 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2280 |     break; | 
 | 2281 |  | 
 | 2282 |   default: | 
| David Blaikie | b219cfc | 2011-09-23 05:06:16 +0000 | [diff] [blame] | 2283 |     llvm_unreachable("Improper first standard conversion"); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2284 |   } | 
 | 2285 |  | 
 | 2286 |   // Perform the second implicit conversion | 
 | 2287 |   switch (SCS.Second) { | 
 | 2288 |   case ICK_Identity: | 
| Sebastian Redl | 2c7588f | 2009-10-10 12:04:10 +0000 | [diff] [blame] | 2289 |     // If both sides are functions (or pointers/references to them), there could | 
 | 2290 |     // be incompatible exception declarations. | 
 | 2291 |     if (CheckExceptionSpecCompatibility(From, ToType)) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2292 |       return ExprError(); | 
| Sebastian Redl | 2c7588f | 2009-10-10 12:04:10 +0000 | [diff] [blame] | 2293 |     // Nothing else to do. | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2294 |     break; | 
 | 2295 |  | 
| Douglas Gregor | 43c79c2 | 2009-12-09 00:47:37 +0000 | [diff] [blame] | 2296 |   case ICK_NoReturn_Adjustment: | 
 | 2297 |     // If both sides are functions (or pointers/references to them), there could | 
 | 2298 |     // be incompatible exception declarations. | 
 | 2299 |     if (CheckExceptionSpecCompatibility(From, ToType)) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2300 |       return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2301 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2302 |     From = ImpCastExprToType(From, ToType, CK_NoOp,  | 
 | 2303 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Douglas Gregor | 43c79c2 | 2009-12-09 00:47:37 +0000 | [diff] [blame] | 2304 |     break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2305 |  | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2306 |   case ICK_Integral_Promotion: | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2307 |   case ICK_Integral_Conversion: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2308 |     From = ImpCastExprToType(From, ToType, CK_IntegralCast,  | 
 | 2309 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 2310 |     break; | 
 | 2311 |  | 
 | 2312 |   case ICK_Floating_Promotion: | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2313 |   case ICK_Floating_Conversion: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2314 |     From = ImpCastExprToType(From, ToType, CK_FloatingCast,  | 
 | 2315 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 2316 |     break; | 
 | 2317 |  | 
 | 2318 |   case ICK_Complex_Promotion: | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2319 |   case ICK_Complex_Conversion: { | 
 | 2320 |     QualType FromEl = From->getType()->getAs<ComplexType>()->getElementType(); | 
 | 2321 |     QualType ToEl = ToType->getAs<ComplexType>()->getElementType(); | 
 | 2322 |     CastKind CK; | 
 | 2323 |     if (FromEl->isRealFloatingType()) { | 
 | 2324 |       if (ToEl->isRealFloatingType()) | 
 | 2325 |         CK = CK_FloatingComplexCast; | 
 | 2326 |       else | 
 | 2327 |         CK = CK_FloatingComplexToIntegralComplex; | 
 | 2328 |     } else if (ToEl->isRealFloatingType()) { | 
 | 2329 |       CK = CK_IntegralComplexToFloatingComplex; | 
 | 2330 |     } else { | 
 | 2331 |       CK = CK_IntegralComplexCast; | 
 | 2332 |     } | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2333 |     From = ImpCastExprToType(From, ToType, CK,  | 
 | 2334 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 2335 |     break; | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2336 |   } | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 2337 |  | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2338 |   case ICK_Floating_Integral: | 
| Douglas Gregor | 0c293ea | 2010-06-22 23:07:26 +0000 | [diff] [blame] | 2339 |     if (ToType->isRealFloatingType()) | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2340 |       From = ImpCastExprToType(From, ToType, CK_IntegralToFloating,  | 
 | 2341 |                                VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 2342 |     else | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2343 |       From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral,  | 
 | 2344 |                                VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 2345 |     break; | 
 | 2346 |  | 
| Douglas Gregor | f9201e0 | 2009-02-11 23:02:49 +0000 | [diff] [blame] | 2347 |   case ICK_Compatible_Conversion: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2348 |       From = ImpCastExprToType(From, ToType, CK_NoOp,  | 
 | 2349 |                                VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2350 |     break; | 
 | 2351 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2352 |   case ICK_Writeback_Conversion: | 
| Anders Carlsson | 61faec1 | 2009-09-12 04:46:44 +0000 | [diff] [blame] | 2353 |   case ICK_Pointer_Conversion: { | 
| Douglas Gregor | a3998bd | 2010-12-02 21:47:04 +0000 | [diff] [blame] | 2354 |     if (SCS.IncompatibleObjC && Action != AA_Casting) { | 
| Douglas Gregor | 45920e8 | 2008-12-19 17:40:08 +0000 | [diff] [blame] | 2355 |       // Diagnose incompatible Objective-C conversions | 
| Douglas Gregor | 8cf0d22 | 2011-06-11 04:42:12 +0000 | [diff] [blame] | 2356 |       if (Action == AA_Initializing || Action == AA_Assigning) | 
| Fariborz Jahanian | 84950c7 | 2011-03-21 19:08:42 +0000 | [diff] [blame] | 2357 |         Diag(From->getSourceRange().getBegin(), | 
 | 2358 |              diag::ext_typecheck_convert_incompatible_pointer) | 
 | 2359 |           << ToType << From->getType() << Action | 
| Anna Zaks | 6722155 | 2011-07-28 19:51:27 +0000 | [diff] [blame] | 2360 |           << From->getSourceRange() << 0; | 
| Fariborz Jahanian | 84950c7 | 2011-03-21 19:08:42 +0000 | [diff] [blame] | 2361 |       else | 
 | 2362 |         Diag(From->getSourceRange().getBegin(), | 
 | 2363 |              diag::ext_typecheck_convert_incompatible_pointer) | 
 | 2364 |           << From->getType() << ToType << Action | 
| Anna Zaks | 6722155 | 2011-07-28 19:51:27 +0000 | [diff] [blame] | 2365 |           << From->getSourceRange() << 0; | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2366 |  | 
| Douglas Gregor | 926df6c | 2011-06-11 01:09:30 +0000 | [diff] [blame] | 2367 |       if (From->getType()->isObjCObjectPointerType() && | 
 | 2368 |           ToType->isObjCObjectPointerType()) | 
 | 2369 |         EmitRelatedResultTypeNote(From); | 
| Fariborz Jahanian | 82007c3 | 2011-07-08 17:41:42 +0000 | [diff] [blame] | 2370 |     }  | 
 | 2371 |     else if (getLangOptions().ObjCAutoRefCount && | 
 | 2372 |              !CheckObjCARCUnavailableWeakConversion(ToType,  | 
 | 2373 |                                                     From->getType())) { | 
| John McCall | 7f3a6d3 | 2011-09-09 06:12:06 +0000 | [diff] [blame] | 2374 |       if (Action == AA_Initializing) | 
 | 2375 |         Diag(From->getSourceRange().getBegin(),  | 
 | 2376 |              diag::err_arc_weak_unavailable_assign); | 
 | 2377 |       else | 
 | 2378 |         Diag(From->getSourceRange().getBegin(), | 
 | 2379 |              diag::err_arc_convesion_of_weak_unavailable)  | 
 | 2380 |           << (Action == AA_Casting) << From->getType() << ToType  | 
 | 2381 |           << From->getSourceRange(); | 
 | 2382 |     } | 
| Fariborz Jahanian | 82007c3 | 2011-07-08 17:41:42 +0000 | [diff] [blame] | 2383 |               | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2384 |     CastKind Kind = CK_Invalid; | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 2385 |     CXXCastPath BasePath; | 
| Douglas Gregor | 14d0aee | 2011-01-27 00:58:17 +0000 | [diff] [blame] | 2386 |     if (CheckPointerConversion(From, ToType, Kind, BasePath, CStyle)) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2387 |       return ExprError(); | 
| John McCall | dc05b11 | 2011-09-10 01:16:55 +0000 | [diff] [blame] | 2388 |  | 
 | 2389 |     // Make sure we extend blocks if necessary. | 
 | 2390 |     // FIXME: doing this here is really ugly. | 
 | 2391 |     if (Kind == CK_BlockPointerToObjCPointerCast) { | 
 | 2392 |       ExprResult E = From; | 
 | 2393 |       (void) PrepareCastToObjCObjectPointer(E); | 
 | 2394 |       From = E.take(); | 
 | 2395 |     } | 
 | 2396 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2397 |     From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) | 
 | 2398 |              .take(); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2399 |     break; | 
| Anders Carlsson | 61faec1 | 2009-09-12 04:46:44 +0000 | [diff] [blame] | 2400 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2401 |  | 
| Anders Carlsson | 61faec1 | 2009-09-12 04:46:44 +0000 | [diff] [blame] | 2402 |   case ICK_Pointer_Member: { | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2403 |     CastKind Kind = CK_Invalid; | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 2404 |     CXXCastPath BasePath; | 
| Douglas Gregor | 14d0aee | 2011-01-27 00:58:17 +0000 | [diff] [blame] | 2405 |     if (CheckMemberPointerConversion(From, ToType, Kind, BasePath, CStyle)) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2406 |       return ExprError(); | 
| Sebastian Redl | 2c7588f | 2009-10-10 12:04:10 +0000 | [diff] [blame] | 2407 |     if (CheckExceptionSpecCompatibility(From, ToType)) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2408 |       return ExprError(); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2409 |     From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) | 
 | 2410 |              .take(); | 
| Anders Carlsson | 61faec1 | 2009-09-12 04:46:44 +0000 | [diff] [blame] | 2411 |     break; | 
 | 2412 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2413 |  | 
| Abramo Bagnara | 737d544 | 2011-04-07 09:26:19 +0000 | [diff] [blame] | 2414 |   case ICK_Boolean_Conversion: | 
| Anton Korobeynikov | aa4a99b | 2011-10-14 23:23:15 +0000 | [diff] [blame] | 2415 |     // Perform half-to-boolean conversion via float. | 
 | 2416 |     if (From->getType()->isHalfType()) { | 
 | 2417 |       From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).take(); | 
 | 2418 |       FromType = Context.FloatTy; | 
 | 2419 |     } | 
 | 2420 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2421 |     From = ImpCastExprToType(From, Context.BoolTy, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2422 |                              ScalarTypeToBooleanCastKind(FromType),  | 
 | 2423 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2424 |     break; | 
 | 2425 |  | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 2426 |   case ICK_Derived_To_Base: { | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 2427 |     CXXCastPath BasePath; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2428 |     if (CheckDerivedToBaseConversion(From->getType(), | 
| Douglas Gregor | b7a86f5 | 2009-11-06 01:02:41 +0000 | [diff] [blame] | 2429 |                                      ToType.getNonReferenceType(), | 
 | 2430 |                                      From->getLocStart(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2431 |                                      From->getSourceRange(), | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 2432 |                                      &BasePath, | 
| Douglas Gregor | 14d0aee | 2011-01-27 00:58:17 +0000 | [diff] [blame] | 2433 |                                      CStyle)) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2434 |       return ExprError(); | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 2435 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2436 |     From = ImpCastExprToType(From, ToType.getNonReferenceType(), | 
| Eli Friedman | c1c0dfb | 2011-09-27 21:58:52 +0000 | [diff] [blame] | 2437 |                       CK_DerivedToBase, From->getValueKind(), | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2438 |                       &BasePath, CCK).take(); | 
| Douglas Gregor | b7a86f5 | 2009-11-06 01:02:41 +0000 | [diff] [blame] | 2439 |     break; | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 2440 |   } | 
 | 2441 |  | 
| Douglas Gregor | fb4a543 | 2010-05-18 22:42:18 +0000 | [diff] [blame] | 2442 |   case ICK_Vector_Conversion: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2443 |     From = ImpCastExprToType(From, ToType, CK_BitCast,  | 
 | 2444 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Douglas Gregor | fb4a543 | 2010-05-18 22:42:18 +0000 | [diff] [blame] | 2445 |     break; | 
 | 2446 |  | 
 | 2447 |   case ICK_Vector_Splat: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2448 |     From = ImpCastExprToType(From, ToType, CK_VectorSplat,  | 
 | 2449 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
| Douglas Gregor | fb4a543 | 2010-05-18 22:42:18 +0000 | [diff] [blame] | 2450 |     break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2451 |  | 
| Douglas Gregor | fb4a543 | 2010-05-18 22:42:18 +0000 | [diff] [blame] | 2452 |   case ICK_Complex_Real: | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2453 |     // Case 1.  x -> _Complex y | 
 | 2454 |     if (const ComplexType *ToComplex = ToType->getAs<ComplexType>()) { | 
 | 2455 |       QualType ElType = ToComplex->getElementType(); | 
 | 2456 |       bool isFloatingComplex = ElType->isRealFloatingType(); | 
 | 2457 |  | 
 | 2458 |       // x -> y | 
 | 2459 |       if (Context.hasSameUnqualifiedType(ElType, From->getType())) { | 
 | 2460 |         // do nothing | 
 | 2461 |       } else if (From->getType()->isRealFloatingType()) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2462 |         From = ImpCastExprToType(From, ElType, | 
 | 2463 |                 isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).take(); | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2464 |       } else { | 
 | 2465 |         assert(From->getType()->isIntegerType()); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2466 |         From = ImpCastExprToType(From, ElType, | 
 | 2467 |                 isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).take(); | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2468 |       } | 
 | 2469 |       // y -> _Complex y | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2470 |       From = ImpCastExprToType(From, ToType, | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2471 |                    isFloatingComplex ? CK_FloatingRealToComplex | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2472 |                                      : CK_IntegralRealToComplex).take(); | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2473 |  | 
 | 2474 |     // Case 2.  _Complex x -> y | 
 | 2475 |     } else { | 
 | 2476 |       const ComplexType *FromComplex = From->getType()->getAs<ComplexType>(); | 
 | 2477 |       assert(FromComplex); | 
 | 2478 |  | 
 | 2479 |       QualType ElType = FromComplex->getElementType(); | 
 | 2480 |       bool isFloatingComplex = ElType->isRealFloatingType(); | 
 | 2481 |  | 
 | 2482 |       // _Complex x -> x | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2483 |       From = ImpCastExprToType(From, ElType, | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2484 |                    isFloatingComplex ? CK_FloatingComplexToReal | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2485 |                                      : CK_IntegralComplexToReal,  | 
 | 2486 |                                VK_RValue, /*BasePath=*/0, CCK).take(); | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2487 |  | 
 | 2488 |       // x -> y | 
 | 2489 |       if (Context.hasSameUnqualifiedType(ElType, ToType)) { | 
 | 2490 |         // do nothing | 
 | 2491 |       } else if (ToType->isRealFloatingType()) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2492 |         From = ImpCastExprToType(From, ToType, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2493 |                    isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating,  | 
 | 2494 |                                  VK_RValue, /*BasePath=*/0, CCK).take(); | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2495 |       } else { | 
 | 2496 |         assert(ToType->isIntegerType()); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2497 |         From = ImpCastExprToType(From, ToType, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2498 |                    isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast,  | 
 | 2499 |                                  VK_RValue, /*BasePath=*/0, CCK).take(); | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 2500 |       } | 
 | 2501 |     } | 
| Douglas Gregor | fb4a543 | 2010-05-18 22:42:18 +0000 | [diff] [blame] | 2502 |     break; | 
| Fariborz Jahanian | e3c8c64 | 2011-02-12 19:07:46 +0000 | [diff] [blame] | 2503 |    | 
 | 2504 |   case ICK_Block_Pointer_Conversion: { | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2505 |     From = ImpCastExprToType(From, ToType.getUnqualifiedType(), CK_BitCast, | 
 | 2506 |                              VK_RValue, /*BasePath=*/0, CCK).take(); | 
 | 2507 |     break; | 
 | 2508 |   } | 
| Fariborz Jahanian | e3c8c64 | 2011-02-12 19:07:46 +0000 | [diff] [blame] | 2509 |        | 
| Fariborz Jahanian | d97f558 | 2011-03-23 19:50:54 +0000 | [diff] [blame] | 2510 |   case ICK_TransparentUnionConversion: { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2511 |     ExprResult FromRes = Owned(From); | 
| Fariborz Jahanian | d97f558 | 2011-03-23 19:50:54 +0000 | [diff] [blame] | 2512 |     Sema::AssignConvertType ConvTy = | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2513 |       CheckTransparentUnionArgumentConstraints(ToType, FromRes); | 
 | 2514 |     if (FromRes.isInvalid()) | 
 | 2515 |       return ExprError(); | 
 | 2516 |     From = FromRes.take(); | 
| Fariborz Jahanian | d97f558 | 2011-03-23 19:50:54 +0000 | [diff] [blame] | 2517 |     assert ((ConvTy == Sema::Compatible) && | 
 | 2518 |             "Improper transparent union conversion"); | 
 | 2519 |     (void)ConvTy; | 
 | 2520 |     break; | 
 | 2521 |   } | 
 | 2522 |  | 
| Douglas Gregor | fb4a543 | 2010-05-18 22:42:18 +0000 | [diff] [blame] | 2523 |   case ICK_Lvalue_To_Rvalue: | 
 | 2524 |   case ICK_Array_To_Pointer: | 
 | 2525 |   case ICK_Function_To_Pointer: | 
 | 2526 |   case ICK_Qualification: | 
 | 2527 |   case ICK_Num_Conversion_Kinds: | 
| David Blaikie | b219cfc | 2011-09-23 05:06:16 +0000 | [diff] [blame] | 2528 |     llvm_unreachable("Improper second standard conversion"); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2529 |   } | 
 | 2530 |  | 
 | 2531 |   switch (SCS.Third) { | 
 | 2532 |   case ICK_Identity: | 
 | 2533 |     // Nothing to do. | 
 | 2534 |     break; | 
 | 2535 |  | 
| Sebastian Redl | 906082e | 2010-07-20 04:20:21 +0000 | [diff] [blame] | 2536 |   case ICK_Qualification: { | 
 | 2537 |     // The qualification keeps the category of the inner expression, unless the | 
 | 2538 |     // target type isn't a reference. | 
| John McCall | 5baba9d | 2010-08-25 10:28:54 +0000 | [diff] [blame] | 2539 |     ExprValueKind VK = ToType->isReferenceType() ? | 
| Eli Friedman | c1c0dfb | 2011-09-27 21:58:52 +0000 | [diff] [blame] | 2540 |                                   From->getValueKind() : VK_RValue; | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2541 |     From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2542 |                              CK_NoOp, VK, /*BasePath=*/0, CCK).take(); | 
| Douglas Gregor | a9bff30 | 2010-02-28 18:30:25 +0000 | [diff] [blame] | 2543 |  | 
| Douglas Gregor | 069a6da | 2011-03-14 16:13:32 +0000 | [diff] [blame] | 2544 |     if (SCS.DeprecatedStringLiteralToCharPtr && | 
 | 2545 |         !getLangOptions().WritableStrings) | 
| Douglas Gregor | a9bff30 | 2010-02-28 18:30:25 +0000 | [diff] [blame] | 2546 |       Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion) | 
 | 2547 |         << ToType.getNonReferenceType(); | 
 | 2548 |  | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2549 |     break; | 
| Sebastian Redl | 906082e | 2010-07-20 04:20:21 +0000 | [diff] [blame] | 2550 |     } | 
 | 2551 |  | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2552 |   default: | 
| David Blaikie | b219cfc | 2011-09-23 05:06:16 +0000 | [diff] [blame] | 2553 |     llvm_unreachable("Improper third standard conversion"); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2554 |   } | 
 | 2555 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 2556 |   return Owned(From); | 
| Douglas Gregor | 94b1dd2 | 2008-10-24 04:54:22 +0000 | [diff] [blame] | 2557 | } | 
 | 2558 |  | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2559 | ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait UTT, | 
| Douglas Gregor | 3d37c0a | 2010-09-09 16:14:44 +0000 | [diff] [blame] | 2560 |                                      SourceLocation KWLoc, | 
 | 2561 |                                      ParsedType Ty, | 
 | 2562 |                                      SourceLocation RParen) { | 
 | 2563 |   TypeSourceInfo *TSInfo; | 
 | 2564 |   QualType T = GetTypeFromParser(Ty, &TSInfo); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2565 |  | 
| Douglas Gregor | 3d37c0a | 2010-09-09 16:14:44 +0000 | [diff] [blame] | 2566 |   if (!TSInfo) | 
 | 2567 |     TSInfo = Context.getTrivialTypeSourceInfo(T); | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2568 |   return BuildUnaryTypeTrait(UTT, KWLoc, TSInfo, RParen); | 
| Douglas Gregor | 3d37c0a | 2010-09-09 16:14:44 +0000 | [diff] [blame] | 2569 | } | 
 | 2570 |  | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2571 | /// \brief Check the completeness of a type in a unary type trait. | 
 | 2572 | /// | 
 | 2573 | /// If the particular type trait requires a complete type, tries to complete | 
 | 2574 | /// it. If completing the type fails, a diagnostic is emitted and false | 
 | 2575 | /// returned. If completing the type succeeds or no completion was required, | 
 | 2576 | /// returns true. | 
 | 2577 | static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, | 
 | 2578 |                                                 UnaryTypeTrait UTT, | 
 | 2579 |                                                 SourceLocation Loc, | 
 | 2580 |                                                 QualType ArgTy) { | 
 | 2581 |   // C++0x [meta.unary.prop]p3: | 
 | 2582 |   //   For all of the class templates X declared in this Clause, instantiating | 
 | 2583 |   //   that template with a template argument that is a class template | 
 | 2584 |   //   specialization may result in the implicit instantiation of the template | 
 | 2585 |   //   argument if and only if the semantics of X require that the argument | 
 | 2586 |   //   must be a complete type. | 
 | 2587 |   // We apply this rule to all the type trait expressions used to implement | 
 | 2588 |   // these class templates. We also try to follow any GCC documented behavior | 
 | 2589 |   // in these expressions to ensure portability of standard libraries. | 
 | 2590 |   switch (UTT) { | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2591 |     // is_complete_type somewhat obviously cannot require a complete type. | 
 | 2592 |   case UTT_IsCompleteType: | 
| Chandler Carruth | d6efe9b | 2011-05-01 19:18:02 +0000 | [diff] [blame] | 2593 |     // Fall-through | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2594 |  | 
 | 2595 |     // These traits are modeled on the type predicates in C++0x | 
 | 2596 |     // [meta.unary.cat] and [meta.unary.comp]. They are not specified as | 
 | 2597 |     // requiring a complete type, as whether or not they return true cannot be | 
 | 2598 |     // impacted by the completeness of the type. | 
 | 2599 |   case UTT_IsVoid: | 
 | 2600 |   case UTT_IsIntegral: | 
 | 2601 |   case UTT_IsFloatingPoint: | 
 | 2602 |   case UTT_IsArray: | 
 | 2603 |   case UTT_IsPointer: | 
 | 2604 |   case UTT_IsLvalueReference: | 
 | 2605 |   case UTT_IsRvalueReference: | 
 | 2606 |   case UTT_IsMemberFunctionPointer: | 
 | 2607 |   case UTT_IsMemberObjectPointer: | 
 | 2608 |   case UTT_IsEnum: | 
 | 2609 |   case UTT_IsUnion: | 
 | 2610 |   case UTT_IsClass: | 
 | 2611 |   case UTT_IsFunction: | 
 | 2612 |   case UTT_IsReference: | 
 | 2613 |   case UTT_IsArithmetic: | 
 | 2614 |   case UTT_IsFundamental: | 
 | 2615 |   case UTT_IsObject: | 
 | 2616 |   case UTT_IsScalar: | 
 | 2617 |   case UTT_IsCompound: | 
 | 2618 |   case UTT_IsMemberPointer: | 
| Chandler Carruth | d6efe9b | 2011-05-01 19:18:02 +0000 | [diff] [blame] | 2619 |     // Fall-through | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2620 |  | 
 | 2621 |     // These traits are modeled on type predicates in C++0x [meta.unary.prop] | 
 | 2622 |     // which requires some of its traits to have the complete type. However, | 
 | 2623 |     // the completeness of the type cannot impact these traits' semantics, and | 
 | 2624 |     // so they don't require it. This matches the comments on these traits in | 
 | 2625 |     // Table 49. | 
 | 2626 |   case UTT_IsConst: | 
 | 2627 |   case UTT_IsVolatile: | 
 | 2628 |   case UTT_IsSigned: | 
 | 2629 |   case UTT_IsUnsigned: | 
 | 2630 |     return true; | 
 | 2631 |  | 
 | 2632 |     // C++0x [meta.unary.prop] Table 49 requires the following traits to be | 
| Chandler Carruth | d6efe9b | 2011-05-01 19:18:02 +0000 | [diff] [blame] | 2633 |     // applied to a complete type. | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2634 |   case UTT_IsTrivial: | 
| Sean Hunt | feb375d | 2011-05-13 00:31:07 +0000 | [diff] [blame] | 2635 |   case UTT_IsTriviallyCopyable: | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2636 |   case UTT_IsStandardLayout: | 
 | 2637 |   case UTT_IsPOD: | 
 | 2638 |   case UTT_IsLiteral: | 
 | 2639 |   case UTT_IsEmpty: | 
 | 2640 |   case UTT_IsPolymorphic: | 
 | 2641 |   case UTT_IsAbstract: | 
| Chandler Carruth | d6efe9b | 2011-05-01 19:18:02 +0000 | [diff] [blame] | 2642 |     // Fall-through | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2643 |  | 
| Chandler Carruth | d6efe9b | 2011-05-01 19:18:02 +0000 | [diff] [blame] | 2644 |     // These trait expressions are designed to help implement predicates in | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2645 |     // [meta.unary.prop] despite not being named the same. They are specified | 
 | 2646 |     // by both GCC and the Embarcadero C++ compiler, and require the complete | 
 | 2647 |     // type due to the overarching C++0x type predicates being implemented | 
 | 2648 |     // requiring the complete type. | 
 | 2649 |   case UTT_HasNothrowAssign: | 
 | 2650 |   case UTT_HasNothrowConstructor: | 
 | 2651 |   case UTT_HasNothrowCopy: | 
 | 2652 |   case UTT_HasTrivialAssign: | 
| Sean Hunt | 023df37 | 2011-05-09 18:22:59 +0000 | [diff] [blame] | 2653 |   case UTT_HasTrivialDefaultConstructor: | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2654 |   case UTT_HasTrivialCopy: | 
 | 2655 |   case UTT_HasTrivialDestructor: | 
 | 2656 |   case UTT_HasVirtualDestructor: | 
 | 2657 |     // Arrays of unknown bound are expressly allowed. | 
 | 2658 |     QualType ElTy = ArgTy; | 
 | 2659 |     if (ArgTy->isIncompleteArrayType()) | 
 | 2660 |       ElTy = S.Context.getAsArrayType(ArgTy)->getElementType(); | 
 | 2661 |  | 
 | 2662 |     // The void type is expressly allowed. | 
 | 2663 |     if (ElTy->isVoidType()) | 
 | 2664 |       return true; | 
 | 2665 |  | 
 | 2666 |     return !S.RequireCompleteType( | 
 | 2667 |       Loc, ElTy, diag::err_incomplete_type_used_in_type_trait_expr); | 
| John Wiegley | cf56641 | 2011-04-28 02:06:46 +0000 | [diff] [blame] | 2668 |   } | 
| Chandler Carruth | 73e0a91 | 2011-05-01 07:23:17 +0000 | [diff] [blame] | 2669 |   llvm_unreachable("Type trait not handled by switch"); | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2670 | } | 
 | 2671 |  | 
 | 2672 | static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, | 
 | 2673 |                                    SourceLocation KeyLoc, QualType T) { | 
| Chandler Carruth | d064c70 | 2011-05-01 08:41:10 +0000 | [diff] [blame] | 2674 |   assert(!T->isDependentType() && "Cannot evaluate traits of dependent type"); | 
| John Wiegley | cf56641 | 2011-04-28 02:06:46 +0000 | [diff] [blame] | 2675 |  | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2676 |   ASTContext &C = Self.Context; | 
 | 2677 |   switch(UTT) { | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2678 |     // Type trait expressions corresponding to the primary type category | 
 | 2679 |     // predicates in C++0x [meta.unary.cat]. | 
 | 2680 |   case UTT_IsVoid: | 
 | 2681 |     return T->isVoidType(); | 
 | 2682 |   case UTT_IsIntegral: | 
 | 2683 |     return T->isIntegralType(C); | 
 | 2684 |   case UTT_IsFloatingPoint: | 
 | 2685 |     return T->isFloatingType(); | 
 | 2686 |   case UTT_IsArray: | 
 | 2687 |     return T->isArrayType(); | 
 | 2688 |   case UTT_IsPointer: | 
 | 2689 |     return T->isPointerType(); | 
 | 2690 |   case UTT_IsLvalueReference: | 
 | 2691 |     return T->isLValueReferenceType(); | 
 | 2692 |   case UTT_IsRvalueReference: | 
 | 2693 |     return T->isRValueReferenceType(); | 
 | 2694 |   case UTT_IsMemberFunctionPointer: | 
 | 2695 |     return T->isMemberFunctionPointerType(); | 
 | 2696 |   case UTT_IsMemberObjectPointer: | 
 | 2697 |     return T->isMemberDataPointerType(); | 
 | 2698 |   case UTT_IsEnum: | 
 | 2699 |     return T->isEnumeralType(); | 
| Chandler Carruth | 28eeb38 | 2011-05-01 06:11:03 +0000 | [diff] [blame] | 2700 |   case UTT_IsUnion: | 
| Chandler Carruth | aaf147b | 2011-05-01 09:29:58 +0000 | [diff] [blame] | 2701 |     return T->isUnionType(); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2702 |   case UTT_IsClass: | 
| Chandler Carruth | aaf147b | 2011-05-01 09:29:58 +0000 | [diff] [blame] | 2703 |     return T->isClassType() || T->isStructureType(); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2704 |   case UTT_IsFunction: | 
 | 2705 |     return T->isFunctionType(); | 
 | 2706 |  | 
 | 2707 |     // Type trait expressions which correspond to the convenient composition | 
 | 2708 |     // predicates in C++0x [meta.unary.comp]. | 
 | 2709 |   case UTT_IsReference: | 
 | 2710 |     return T->isReferenceType(); | 
 | 2711 |   case UTT_IsArithmetic: | 
| Chandler Carruth | aaf147b | 2011-05-01 09:29:58 +0000 | [diff] [blame] | 2712 |     return T->isArithmeticType() && !T->isEnumeralType(); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2713 |   case UTT_IsFundamental: | 
| Chandler Carruth | aaf147b | 2011-05-01 09:29:58 +0000 | [diff] [blame] | 2714 |     return T->isFundamentalType(); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2715 |   case UTT_IsObject: | 
| Chandler Carruth | aaf147b | 2011-05-01 09:29:58 +0000 | [diff] [blame] | 2716 |     return T->isObjectType(); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2717 |   case UTT_IsScalar: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2718 |     // Note: semantic analysis depends on Objective-C lifetime types to be | 
 | 2719 |     // considered scalar types. However, such types do not actually behave | 
 | 2720 |     // like scalar types at run time (since they may require retain/release | 
 | 2721 |     // operations), so we report them as non-scalar. | 
 | 2722 |     if (T->isObjCLifetimeType()) { | 
 | 2723 |       switch (T.getObjCLifetime()) { | 
 | 2724 |       case Qualifiers::OCL_None: | 
 | 2725 |       case Qualifiers::OCL_ExplicitNone: | 
 | 2726 |         return true; | 
 | 2727 |  | 
 | 2728 |       case Qualifiers::OCL_Strong: | 
 | 2729 |       case Qualifiers::OCL_Weak: | 
 | 2730 |       case Qualifiers::OCL_Autoreleasing: | 
 | 2731 |         return false; | 
 | 2732 |       } | 
 | 2733 |     } | 
 | 2734 |        | 
| Chandler Carruth | cec0ced | 2011-05-01 09:29:55 +0000 | [diff] [blame] | 2735 |     return T->isScalarType(); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2736 |   case UTT_IsCompound: | 
| Chandler Carruth | aaf147b | 2011-05-01 09:29:58 +0000 | [diff] [blame] | 2737 |     return T->isCompoundType(); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2738 |   case UTT_IsMemberPointer: | 
 | 2739 |     return T->isMemberPointerType(); | 
 | 2740 |  | 
 | 2741 |     // Type trait expressions which correspond to the type property predicates | 
 | 2742 |     // in C++0x [meta.unary.prop]. | 
 | 2743 |   case UTT_IsConst: | 
 | 2744 |     return T.isConstQualified(); | 
 | 2745 |   case UTT_IsVolatile: | 
 | 2746 |     return T.isVolatileQualified(); | 
 | 2747 |   case UTT_IsTrivial: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2748 |     return T.isTrivialType(Self.Context); | 
| Sean Hunt | feb375d | 2011-05-13 00:31:07 +0000 | [diff] [blame] | 2749 |   case UTT_IsTriviallyCopyable: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2750 |     return T.isTriviallyCopyableType(Self.Context); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2751 |   case UTT_IsStandardLayout: | 
 | 2752 |     return T->isStandardLayoutType(); | 
 | 2753 |   case UTT_IsPOD: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2754 |     return T.isPODType(Self.Context); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2755 |   case UTT_IsLiteral: | 
 | 2756 |     return T->isLiteralType(); | 
 | 2757 |   case UTT_IsEmpty: | 
 | 2758 |     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) | 
 | 2759 |       return !RD->isUnion() && RD->isEmpty(); | 
 | 2760 |     return false; | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2761 |   case UTT_IsPolymorphic: | 
| Chandler Carruth | 28eeb38 | 2011-05-01 06:11:03 +0000 | [diff] [blame] | 2762 |     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) | 
 | 2763 |       return RD->isPolymorphic(); | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2764 |     return false; | 
 | 2765 |   case UTT_IsAbstract: | 
| Chandler Carruth | 28eeb38 | 2011-05-01 06:11:03 +0000 | [diff] [blame] | 2766 |     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) | 
 | 2767 |       return RD->isAbstract(); | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2768 |     return false; | 
| John Wiegley | 20c0da7 | 2011-04-27 23:09:49 +0000 | [diff] [blame] | 2769 |   case UTT_IsSigned: | 
 | 2770 |     return T->isSignedIntegerType(); | 
| John Wiegley | 20c0da7 | 2011-04-27 23:09:49 +0000 | [diff] [blame] | 2771 |   case UTT_IsUnsigned: | 
 | 2772 |     return T->isUnsignedIntegerType(); | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2773 |  | 
 | 2774 |     // Type trait expressions which query classes regarding their construction, | 
 | 2775 |     // destruction, and copying. Rather than being based directly on the | 
 | 2776 |     // related type predicates in the standard, they are specified by both | 
 | 2777 |     // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those | 
 | 2778 |     // specifications. | 
 | 2779 |     // | 
 | 2780 |     //   1: http://gcc.gnu/.org/onlinedocs/gcc/Type-Traits.html | 
 | 2781 |     //   2: http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index | 
| Sean Hunt | 023df37 | 2011-05-09 18:22:59 +0000 | [diff] [blame] | 2782 |   case UTT_HasTrivialDefaultConstructor: | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2783 |     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: | 
 | 2784 |     //   If __is_pod (type) is true then the trait is true, else if type is | 
 | 2785 |     //   a cv class or union type (or array thereof) with a trivial default | 
 | 2786 |     //   constructor ([class.ctor]) then the trait is true, else it is false. | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2787 |     if (T.isPODType(Self.Context)) | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2788 |       return true; | 
 | 2789 |     if (const RecordType *RT = | 
 | 2790 |           C.getBaseElementType(T)->getAs<RecordType>()) | 
| Sean Hunt | 023df37 | 2011-05-09 18:22:59 +0000 | [diff] [blame] | 2791 |       return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDefaultConstructor(); | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2792 |     return false; | 
 | 2793 |   case UTT_HasTrivialCopy: | 
 | 2794 |     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: | 
 | 2795 |     //   If __is_pod (type) is true or type is a reference type then | 
 | 2796 |     //   the trait is true, else if type is a cv class or union type | 
 | 2797 |     //   with a trivial copy constructor ([class.copy]) then the trait | 
 | 2798 |     //   is true, else it is false. | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2799 |     if (T.isPODType(Self.Context) || T->isReferenceType()) | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2800 |       return true; | 
 | 2801 |     if (const RecordType *RT = T->getAs<RecordType>()) | 
 | 2802 |       return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor(); | 
 | 2803 |     return false; | 
 | 2804 |   case UTT_HasTrivialAssign: | 
 | 2805 |     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: | 
 | 2806 |     //   If type is const qualified or is a reference type then the | 
 | 2807 |     //   trait is false. Otherwise if __is_pod (type) is true then the | 
 | 2808 |     //   trait is true, else if type is a cv class or union type with | 
 | 2809 |     //   a trivial copy assignment ([class.copy]) then the trait is | 
 | 2810 |     //   true, else it is false. | 
 | 2811 |     // Note: the const and reference restrictions are interesting, | 
 | 2812 |     // given that const and reference members don't prevent a class | 
 | 2813 |     // from having a trivial copy assignment operator (but do cause | 
 | 2814 |     // errors if the copy assignment operator is actually used, q.v. | 
 | 2815 |     // [class.copy]p12). | 
 | 2816 |  | 
 | 2817 |     if (C.getBaseElementType(T).isConstQualified()) | 
 | 2818 |       return false; | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2819 |     if (T.isPODType(Self.Context)) | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2820 |       return true; | 
 | 2821 |     if (const RecordType *RT = T->getAs<RecordType>()) | 
 | 2822 |       return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment(); | 
 | 2823 |     return false; | 
 | 2824 |   case UTT_HasTrivialDestructor: | 
 | 2825 |     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: | 
 | 2826 |     //   If __is_pod (type) is true or type is a reference type | 
 | 2827 |     //   then the trait is true, else if type is a cv class or union | 
 | 2828 |     //   type (or array thereof) with a trivial destructor | 
 | 2829 |     //   ([class.dtor]) then the trait is true, else it is | 
 | 2830 |     //   false. | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2831 |     if (T.isPODType(Self.Context) || T->isReferenceType()) | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2832 |       return true; | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2833 |        | 
 | 2834 |     // Objective-C++ ARC: autorelease types don't require destruction. | 
 | 2835 |     if (T->isObjCLifetimeType() &&  | 
 | 2836 |         T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) | 
 | 2837 |       return true; | 
 | 2838 |        | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2839 |     if (const RecordType *RT = | 
 | 2840 |           C.getBaseElementType(T)->getAs<RecordType>()) | 
 | 2841 |       return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor(); | 
 | 2842 |     return false; | 
 | 2843 |   // TODO: Propagate nothrowness for implicitly declared special members. | 
 | 2844 |   case UTT_HasNothrowAssign: | 
 | 2845 |     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: | 
 | 2846 |     //   If type is const qualified or is a reference type then the | 
 | 2847 |     //   trait is false. Otherwise if __has_trivial_assign (type) | 
 | 2848 |     //   is true then the trait is true, else if type is a cv class | 
 | 2849 |     //   or union type with copy assignment operators that are known | 
 | 2850 |     //   not to throw an exception then the trait is true, else it is | 
 | 2851 |     //   false. | 
 | 2852 |     if (C.getBaseElementType(T).isConstQualified()) | 
 | 2853 |       return false; | 
 | 2854 |     if (T->isReferenceType()) | 
 | 2855 |       return false; | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2856 |     if (T.isPODType(Self.Context) || T->isObjCLifetimeType()) | 
 | 2857 |       return true;      | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2858 |     if (const RecordType *RT = T->getAs<RecordType>()) { | 
 | 2859 |       CXXRecordDecl* RD = cast<CXXRecordDecl>(RT->getDecl()); | 
 | 2860 |       if (RD->hasTrivialCopyAssignment()) | 
 | 2861 |         return true; | 
 | 2862 |  | 
 | 2863 |       bool FoundAssign = false; | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2864 |       DeclarationName Name = C.DeclarationNames.getCXXOperatorName(OO_Equal); | 
| Sebastian Redl | f8aca86 | 2010-09-14 23:40:14 +0000 | [diff] [blame] | 2865 |       LookupResult Res(Self, DeclarationNameInfo(Name, KeyLoc), | 
 | 2866 |                        Sema::LookupOrdinaryName); | 
 | 2867 |       if (Self.LookupQualifiedName(Res, RD)) { | 
| Douglas Gregor | d41679d | 2011-10-12 15:40:49 +0000 | [diff] [blame] | 2868 |         Res.suppressDiagnostics(); | 
| Sebastian Redl | f8aca86 | 2010-09-14 23:40:14 +0000 | [diff] [blame] | 2869 |         for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end(); | 
 | 2870 |              Op != OpEnd; ++Op) { | 
| Douglas Gregor | d41679d | 2011-10-12 15:40:49 +0000 | [diff] [blame] | 2871 |           if (isa<FunctionTemplateDecl>(*Op)) | 
 | 2872 |             continue; | 
 | 2873 |            | 
| Sebastian Redl | f8aca86 | 2010-09-14 23:40:14 +0000 | [diff] [blame] | 2874 |           CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op); | 
 | 2875 |           if (Operator->isCopyAssignmentOperator()) { | 
 | 2876 |             FoundAssign = true; | 
 | 2877 |             const FunctionProtoType *CPT | 
 | 2878 |                 = Operator->getType()->getAs<FunctionProtoType>(); | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2879 |             if (CPT->getExceptionSpecType() == EST_Delayed) | 
 | 2880 |               return false; | 
 | 2881 |             if (!CPT->isNothrow(Self.Context)) | 
 | 2882 |               return false; | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2883 |           } | 
 | 2884 |         } | 
 | 2885 |       } | 
| Douglas Gregor | d41679d | 2011-10-12 15:40:49 +0000 | [diff] [blame] | 2886 |        | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2887 |       return FoundAssign; | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2888 |     } | 
 | 2889 |     return false; | 
 | 2890 |   case UTT_HasNothrowCopy: | 
 | 2891 |     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: | 
 | 2892 |     //   If __has_trivial_copy (type) is true then the trait is true, else | 
 | 2893 |     //   if type is a cv class or union type with copy constructors that are | 
 | 2894 |     //   known not to throw an exception then the trait is true, else it is | 
 | 2895 |     //   false. | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2896 |     if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType()) | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2897 |       return true; | 
 | 2898 |     if (const RecordType *RT = T->getAs<RecordType>()) { | 
 | 2899 |       CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); | 
 | 2900 |       if (RD->hasTrivialCopyConstructor()) | 
 | 2901 |         return true; | 
 | 2902 |  | 
 | 2903 |       bool FoundConstructor = false; | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2904 |       unsigned FoundTQs; | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2905 |       DeclContext::lookup_const_iterator Con, ConEnd; | 
| Sebastian Redl | 5f4e899 | 2010-09-13 21:10:20 +0000 | [diff] [blame] | 2906 |       for (llvm::tie(Con, ConEnd) = Self.LookupConstructors(RD); | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2907 |            Con != ConEnd; ++Con) { | 
| Sebastian Redl | 08295a5 | 2010-09-13 22:18:28 +0000 | [diff] [blame] | 2908 |         // A template constructor is never a copy constructor. | 
 | 2909 |         // FIXME: However, it may actually be selected at the actual overload | 
 | 2910 |         // resolution point. | 
 | 2911 |         if (isa<FunctionTemplateDecl>(*Con)) | 
 | 2912 |           continue; | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2913 |         CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); | 
 | 2914 |         if (Constructor->isCopyConstructor(FoundTQs)) { | 
 | 2915 |           FoundConstructor = true; | 
 | 2916 |           const FunctionProtoType *CPT | 
 | 2917 |               = Constructor->getType()->getAs<FunctionProtoType>(); | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2918 |           if (CPT->getExceptionSpecType() == EST_Delayed) | 
 | 2919 |             return false; | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 2920 |           // FIXME: check whether evaluating default arguments can throw. | 
| Sebastian Redl | 751025d | 2010-09-13 22:02:47 +0000 | [diff] [blame] | 2921 |           // For now, we'll be conservative and assume that they can throw. | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2922 |           if (!CPT->isNothrow(Self.Context) || CPT->getNumArgs() > 1) | 
 | 2923 |             return false; | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2924 |         } | 
 | 2925 |       } | 
 | 2926 |  | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2927 |       return FoundConstructor; | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2928 |     } | 
 | 2929 |     return false; | 
 | 2930 |   case UTT_HasNothrowConstructor: | 
 | 2931 |     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: | 
 | 2932 |     //   If __has_trivial_constructor (type) is true then the trait is | 
 | 2933 |     //   true, else if type is a cv class or union type (or array | 
 | 2934 |     //   thereof) with a default constructor that is known not to | 
 | 2935 |     //   throw an exception then the trait is true, else it is false. | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2936 |     if (T.isPODType(C) || T->isObjCLifetimeType()) | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2937 |       return true; | 
 | 2938 |     if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>()) { | 
 | 2939 |       CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); | 
| Sean Hunt | 023df37 | 2011-05-09 18:22:59 +0000 | [diff] [blame] | 2940 |       if (RD->hasTrivialDefaultConstructor()) | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2941 |         return true; | 
 | 2942 |  | 
| Sebastian Redl | 751025d | 2010-09-13 22:02:47 +0000 | [diff] [blame] | 2943 |       DeclContext::lookup_const_iterator Con, ConEnd; | 
 | 2944 |       for (llvm::tie(Con, ConEnd) = Self.LookupConstructors(RD); | 
 | 2945 |            Con != ConEnd; ++Con) { | 
| Sebastian Redl | 08295a5 | 2010-09-13 22:18:28 +0000 | [diff] [blame] | 2946 |         // FIXME: In C++0x, a constructor template can be a default constructor. | 
 | 2947 |         if (isa<FunctionTemplateDecl>(*Con)) | 
 | 2948 |           continue; | 
| Sebastian Redl | 751025d | 2010-09-13 22:02:47 +0000 | [diff] [blame] | 2949 |         CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); | 
 | 2950 |         if (Constructor->isDefaultConstructor()) { | 
 | 2951 |           const FunctionProtoType *CPT | 
 | 2952 |               = Constructor->getType()->getAs<FunctionProtoType>(); | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 2953 |           if (CPT->getExceptionSpecType() == EST_Delayed) | 
 | 2954 |             return false; | 
| Sebastian Redl | 751025d | 2010-09-13 22:02:47 +0000 | [diff] [blame] | 2955 |           // TODO: check whether evaluating default arguments can throw. | 
 | 2956 |           // For now, we'll be conservative and assume that they can throw. | 
| Sebastian Redl | 8026f6d | 2011-03-13 17:09:40 +0000 | [diff] [blame] | 2957 |           return CPT->isNothrow(Self.Context) && CPT->getNumArgs() == 0; | 
| Sebastian Redl | 751025d | 2010-09-13 22:02:47 +0000 | [diff] [blame] | 2958 |         } | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2959 |       } | 
 | 2960 |     } | 
 | 2961 |     return false; | 
 | 2962 |   case UTT_HasVirtualDestructor: | 
 | 2963 |     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html: | 
 | 2964 |     //   If type is a class type with a virtual destructor ([class.dtor]) | 
 | 2965 |     //   then the trait is true, else it is false. | 
 | 2966 |     if (const RecordType *Record = T->getAs<RecordType>()) { | 
 | 2967 |       CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); | 
| Sebastian Redl | f8aca86 | 2010-09-14 23:40:14 +0000 | [diff] [blame] | 2968 |       if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD)) | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2969 |         return Destructor->isVirtual(); | 
 | 2970 |     } | 
 | 2971 |     return false; | 
| Chandler Carruth | c41d6b5 | 2011-05-01 06:11:07 +0000 | [diff] [blame] | 2972 |  | 
 | 2973 |     // These type trait expressions are modeled on the specifications for the | 
 | 2974 |     // Embarcadero C++0x type trait functions: | 
 | 2975 |     //   http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index | 
 | 2976 |   case UTT_IsCompleteType: | 
 | 2977 |     // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_): | 
 | 2978 |     //   Returns True if and only if T is a complete type at the point of the | 
 | 2979 |     //   function call. | 
 | 2980 |     return !T->isIncompleteType(); | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2981 |   } | 
| Chandler Carruth | 83f563c | 2011-05-01 07:44:17 +0000 | [diff] [blame] | 2982 |   llvm_unreachable("Type trait not covered by switch"); | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2983 | } | 
 | 2984 |  | 
 | 2985 | ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT, | 
| Douglas Gregor | 3d37c0a | 2010-09-09 16:14:44 +0000 | [diff] [blame] | 2986 |                                      SourceLocation KWLoc, | 
 | 2987 |                                      TypeSourceInfo *TSInfo, | 
 | 2988 |                                      SourceLocation RParen) { | 
 | 2989 |   QualType T = TSInfo->getType(); | 
| Chandler Carruth | eb65a10 | 2011-04-30 10:07:32 +0000 | [diff] [blame] | 2990 |   if (!CheckUnaryTypeTraitTypeCompleteness(*this, UTT, KWLoc, T)) | 
 | 2991 |     return ExprError(); | 
| Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 2992 |  | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2993 |   bool Value = false; | 
 | 2994 |   if (!T->isDependentType()) | 
| Chandler Carruth | ccb4ecf | 2011-05-01 06:51:22 +0000 | [diff] [blame] | 2995 |     Value = EvaluateUnaryTypeTrait(*this, UTT, KWLoc, T); | 
| Sebastian Redl | 0dfd848 | 2010-09-13 20:56:31 +0000 | [diff] [blame] | 2996 |  | 
 | 2997 |   return Owned(new (Context) UnaryTypeTraitExpr(KWLoc, UTT, TSInfo, Value, | 
| Anders Carlsson | 3292d5c | 2009-07-07 19:06:02 +0000 | [diff] [blame] | 2998 |                                                 RParen, Context.BoolTy)); | 
| Sebastian Redl | 64b45f7 | 2009-01-05 20:52:13 +0000 | [diff] [blame] | 2999 | } | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3000 |  | 
| Francois Pichet | 6ad6f28 | 2010-12-07 00:08:36 +0000 | [diff] [blame] | 3001 | ExprResult Sema::ActOnBinaryTypeTrait(BinaryTypeTrait BTT, | 
 | 3002 |                                       SourceLocation KWLoc, | 
 | 3003 |                                       ParsedType LhsTy, | 
 | 3004 |                                       ParsedType RhsTy, | 
 | 3005 |                                       SourceLocation RParen) { | 
 | 3006 |   TypeSourceInfo *LhsTSInfo; | 
 | 3007 |   QualType LhsT = GetTypeFromParser(LhsTy, &LhsTSInfo); | 
 | 3008 |   if (!LhsTSInfo) | 
 | 3009 |     LhsTSInfo = Context.getTrivialTypeSourceInfo(LhsT); | 
 | 3010 |  | 
 | 3011 |   TypeSourceInfo *RhsTSInfo; | 
 | 3012 |   QualType RhsT = GetTypeFromParser(RhsTy, &RhsTSInfo); | 
 | 3013 |   if (!RhsTSInfo) | 
 | 3014 |     RhsTSInfo = Context.getTrivialTypeSourceInfo(RhsT); | 
 | 3015 |  | 
 | 3016 |   return BuildBinaryTypeTrait(BTT, KWLoc, LhsTSInfo, RhsTSInfo, RParen); | 
 | 3017 | } | 
 | 3018 |  | 
 | 3019 | static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, | 
 | 3020 |                                     QualType LhsT, QualType RhsT, | 
 | 3021 |                                     SourceLocation KeyLoc) { | 
| Chandler Carruth | d064c70 | 2011-05-01 08:41:10 +0000 | [diff] [blame] | 3022 |   assert(!LhsT->isDependentType() && !RhsT->isDependentType() && | 
 | 3023 |          "Cannot evaluate traits of dependent types"); | 
| Francois Pichet | 6ad6f28 | 2010-12-07 00:08:36 +0000 | [diff] [blame] | 3024 |  | 
 | 3025 |   switch(BTT) { | 
| John McCall | d89d30f | 2011-01-28 22:02:36 +0000 | [diff] [blame] | 3026 |   case BTT_IsBaseOf: { | 
| Francois Pichet | 6ad6f28 | 2010-12-07 00:08:36 +0000 | [diff] [blame] | 3027 |     // C++0x [meta.rel]p2 | 
| John McCall | d89d30f | 2011-01-28 22:02:36 +0000 | [diff] [blame] | 3028 |     // Base is a base class of Derived without regard to cv-qualifiers or | 
| Francois Pichet | 6ad6f28 | 2010-12-07 00:08:36 +0000 | [diff] [blame] | 3029 |     // Base and Derived are not unions and name the same class type without | 
 | 3030 |     // regard to cv-qualifiers. | 
| Francois Pichet | 6ad6f28 | 2010-12-07 00:08:36 +0000 | [diff] [blame] | 3031 |  | 
| John McCall | d89d30f | 2011-01-28 22:02:36 +0000 | [diff] [blame] | 3032 |     const RecordType *lhsRecord = LhsT->getAs<RecordType>(); | 
 | 3033 |     if (!lhsRecord) return false; | 
 | 3034 |  | 
 | 3035 |     const RecordType *rhsRecord = RhsT->getAs<RecordType>(); | 
 | 3036 |     if (!rhsRecord) return false; | 
 | 3037 |  | 
 | 3038 |     assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) | 
 | 3039 |              == (lhsRecord == rhsRecord)); | 
 | 3040 |  | 
 | 3041 |     if (lhsRecord == rhsRecord) | 
 | 3042 |       return !lhsRecord->getDecl()->isUnion(); | 
 | 3043 |  | 
 | 3044 |     // C++0x [meta.rel]p2: | 
 | 3045 |     //   If Base and Derived are class types and are different types | 
 | 3046 |     //   (ignoring possible cv-qualifiers) then Derived shall be a | 
 | 3047 |     //   complete type. | 
 | 3048 |     if (Self.RequireCompleteType(KeyLoc, RhsT,  | 
 | 3049 |                           diag::err_incomplete_type_used_in_type_trait_expr)) | 
 | 3050 |       return false; | 
 | 3051 |  | 
 | 3052 |     return cast<CXXRecordDecl>(rhsRecord->getDecl()) | 
 | 3053 |       ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl())); | 
 | 3054 |   } | 
| John Wiegley | 20c0da7 | 2011-04-27 23:09:49 +0000 | [diff] [blame] | 3055 |   case BTT_IsSame: | 
 | 3056 |     return Self.Context.hasSameType(LhsT, RhsT); | 
| Francois Pichet | f187237 | 2010-12-08 22:35:30 +0000 | [diff] [blame] | 3057 |   case BTT_TypeCompatible: | 
 | 3058 |     return Self.Context.typesAreCompatible(LhsT.getUnqualifiedType(), | 
 | 3059 |                                            RhsT.getUnqualifiedType()); | 
| John Wiegley | 20c0da7 | 2011-04-27 23:09:49 +0000 | [diff] [blame] | 3060 |   case BTT_IsConvertible: | 
| Douglas Gregor | 9f36113 | 2011-01-27 20:28:01 +0000 | [diff] [blame] | 3061 |   case BTT_IsConvertibleTo: { | 
 | 3062 |     // C++0x [meta.rel]p4: | 
 | 3063 |     //   Given the following function prototype: | 
 | 3064 |     // | 
 | 3065 |     //     template <class T>  | 
 | 3066 |     //       typename add_rvalue_reference<T>::type create(); | 
 | 3067 |     // | 
 | 3068 |     //   the predicate condition for a template specialization  | 
 | 3069 |     //   is_convertible<From, To> shall be satisfied if and only if  | 
 | 3070 |     //   the return expression in the following code would be  | 
 | 3071 |     //   well-formed, including any implicit conversions to the return | 
 | 3072 |     //   type of the function: | 
 | 3073 |     // | 
 | 3074 |     //     To test() {  | 
 | 3075 |     //       return create<From>(); | 
 | 3076 |     //     } | 
 | 3077 |     // | 
 | 3078 |     //   Access checking is performed as if in a context unrelated to To and  | 
 | 3079 |     //   From. Only the validity of the immediate context of the expression  | 
 | 3080 |     //   of the return-statement (including conversions to the return type) | 
 | 3081 |     //   is considered. | 
 | 3082 |     // | 
 | 3083 |     // We model the initialization as a copy-initialization of a temporary | 
 | 3084 |     // of the appropriate type, which for this expression is identical to the | 
 | 3085 |     // return statement (since NRVO doesn't apply). | 
 | 3086 |     if (LhsT->isObjectType() || LhsT->isFunctionType()) | 
 | 3087 |       LhsT = Self.Context.getRValueReferenceType(LhsT); | 
 | 3088 |      | 
 | 3089 |     InitializedEntity To(InitializedEntity::InitializeTemporary(RhsT)); | 
| Douglas Gregor | b608b98 | 2011-01-28 02:26:04 +0000 | [diff] [blame] | 3090 |     OpaqueValueExpr From(KeyLoc, LhsT.getNonLValueExprType(Self.Context), | 
| Douglas Gregor | 9f36113 | 2011-01-27 20:28:01 +0000 | [diff] [blame] | 3091 |                          Expr::getValueKindForType(LhsT)); | 
 | 3092 |     Expr *FromPtr = &From; | 
 | 3093 |     InitializationKind Kind(InitializationKind::CreateCopy(KeyLoc,  | 
 | 3094 |                                                            SourceLocation())); | 
 | 3095 |      | 
| Douglas Gregor | 1eee5dc | 2011-01-27 22:31:44 +0000 | [diff] [blame] | 3096 |     // Perform the initialization within a SFINAE trap at translation unit  | 
 | 3097 |     // scope. | 
 | 3098 |     Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true); | 
 | 3099 |     Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl()); | 
| Douglas Gregor | 9f36113 | 2011-01-27 20:28:01 +0000 | [diff] [blame] | 3100 |     InitializationSequence Init(Self, To, Kind, &FromPtr, 1); | 
| Sebastian Redl | 383616c | 2011-06-05 12:23:28 +0000 | [diff] [blame] | 3101 |     if (Init.Failed()) | 
| Douglas Gregor | 9f36113 | 2011-01-27 20:28:01 +0000 | [diff] [blame] | 3102 |       return false; | 
| Douglas Gregor | 1eee5dc | 2011-01-27 22:31:44 +0000 | [diff] [blame] | 3103 |  | 
| Douglas Gregor | 9f36113 | 2011-01-27 20:28:01 +0000 | [diff] [blame] | 3104 |     ExprResult Result = Init.Perform(Self, To, Kind, MultiExprArg(&FromPtr, 1)); | 
 | 3105 |     return !Result.isInvalid() && !SFINAE.hasErrorOccurred(); | 
 | 3106 |   } | 
| Francois Pichet | 6ad6f28 | 2010-12-07 00:08:36 +0000 | [diff] [blame] | 3107 |   } | 
 | 3108 |   llvm_unreachable("Unknown type trait or not implemented"); | 
 | 3109 | } | 
 | 3110 |  | 
 | 3111 | ExprResult Sema::BuildBinaryTypeTrait(BinaryTypeTrait BTT, | 
 | 3112 |                                       SourceLocation KWLoc, | 
 | 3113 |                                       TypeSourceInfo *LhsTSInfo, | 
 | 3114 |                                       TypeSourceInfo *RhsTSInfo, | 
 | 3115 |                                       SourceLocation RParen) { | 
 | 3116 |   QualType LhsT = LhsTSInfo->getType(); | 
 | 3117 |   QualType RhsT = RhsTSInfo->getType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3118 |  | 
| John McCall | d89d30f | 2011-01-28 22:02:36 +0000 | [diff] [blame] | 3119 |   if (BTT == BTT_TypeCompatible) { | 
| Francois Pichet | f187237 | 2010-12-08 22:35:30 +0000 | [diff] [blame] | 3120 |     if (getLangOptions().CPlusPlus) { | 
 | 3121 |       Diag(KWLoc, diag::err_types_compatible_p_in_cplusplus) | 
 | 3122 |         << SourceRange(KWLoc, RParen); | 
 | 3123 |       return ExprError(); | 
 | 3124 |     } | 
| Francois Pichet | 6ad6f28 | 2010-12-07 00:08:36 +0000 | [diff] [blame] | 3125 |   } | 
 | 3126 |  | 
 | 3127 |   bool Value = false; | 
 | 3128 |   if (!LhsT->isDependentType() && !RhsT->isDependentType()) | 
 | 3129 |     Value = EvaluateBinaryTypeTrait(*this, BTT, LhsT, RhsT, KWLoc); | 
 | 3130 |  | 
| Francois Pichet | f187237 | 2010-12-08 22:35:30 +0000 | [diff] [blame] | 3131 |   // Select trait result type. | 
 | 3132 |   QualType ResultType; | 
 | 3133 |   switch (BTT) { | 
| Francois Pichet | f187237 | 2010-12-08 22:35:30 +0000 | [diff] [blame] | 3134 |   case BTT_IsBaseOf:       ResultType = Context.BoolTy; break; | 
| John Wiegley | 20c0da7 | 2011-04-27 23:09:49 +0000 | [diff] [blame] | 3135 |   case BTT_IsConvertible:  ResultType = Context.BoolTy; break; | 
 | 3136 |   case BTT_IsSame:         ResultType = Context.BoolTy; break; | 
| Francois Pichet | f187237 | 2010-12-08 22:35:30 +0000 | [diff] [blame] | 3137 |   case BTT_TypeCompatible: ResultType = Context.IntTy; break; | 
| Douglas Gregor | 9f36113 | 2011-01-27 20:28:01 +0000 | [diff] [blame] | 3138 |   case BTT_IsConvertibleTo: ResultType = Context.BoolTy; break; | 
| Francois Pichet | f187237 | 2010-12-08 22:35:30 +0000 | [diff] [blame] | 3139 |   } | 
 | 3140 |  | 
| Francois Pichet | 6ad6f28 | 2010-12-07 00:08:36 +0000 | [diff] [blame] | 3141 |   return Owned(new (Context) BinaryTypeTraitExpr(KWLoc, BTT, LhsTSInfo, | 
 | 3142 |                                                  RhsTSInfo, Value, RParen, | 
| Francois Pichet | f187237 | 2010-12-08 22:35:30 +0000 | [diff] [blame] | 3143 |                                                  ResultType)); | 
| Francois Pichet | 6ad6f28 | 2010-12-07 00:08:36 +0000 | [diff] [blame] | 3144 | } | 
 | 3145 |  | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3146 | ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT, | 
 | 3147 |                                      SourceLocation KWLoc, | 
 | 3148 |                                      ParsedType Ty, | 
 | 3149 |                                      Expr* DimExpr, | 
 | 3150 |                                      SourceLocation RParen) { | 
 | 3151 |   TypeSourceInfo *TSInfo; | 
 | 3152 |   QualType T = GetTypeFromParser(Ty, &TSInfo); | 
 | 3153 |   if (!TSInfo) | 
 | 3154 |     TSInfo = Context.getTrivialTypeSourceInfo(T); | 
 | 3155 |  | 
 | 3156 |   return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen); | 
 | 3157 | } | 
 | 3158 |  | 
 | 3159 | static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, | 
 | 3160 |                                            QualType T, Expr *DimExpr, | 
 | 3161 |                                            SourceLocation KeyLoc) { | 
| Chandler Carruth | d064c70 | 2011-05-01 08:41:10 +0000 | [diff] [blame] | 3162 |   assert(!T->isDependentType() && "Cannot evaluate traits of dependent type"); | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3163 |  | 
 | 3164 |   switch(ATT) { | 
 | 3165 |   case ATT_ArrayRank: | 
 | 3166 |     if (T->isArrayType()) { | 
 | 3167 |       unsigned Dim = 0; | 
 | 3168 |       while (const ArrayType *AT = Self.Context.getAsArrayType(T)) { | 
 | 3169 |         ++Dim; | 
 | 3170 |         T = AT->getElementType(); | 
 | 3171 |       } | 
 | 3172 |       return Dim; | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3173 |     } | 
| John Wiegley | cf56641 | 2011-04-28 02:06:46 +0000 | [diff] [blame] | 3174 |     return 0; | 
 | 3175 |  | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3176 |   case ATT_ArrayExtent: { | 
 | 3177 |     llvm::APSInt Value; | 
 | 3178 |     uint64_t Dim; | 
| John Wiegley | cf56641 | 2011-04-28 02:06:46 +0000 | [diff] [blame] | 3179 |     if (DimExpr->isIntegerConstantExpr(Value, Self.Context, 0, false)) { | 
 | 3180 |       if (Value < llvm::APSInt(Value.getBitWidth(), Value.isUnsigned())) { | 
 | 3181 |         Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer) << | 
 | 3182 |           DimExpr->getSourceRange(); | 
 | 3183 |         return false; | 
 | 3184 |       } | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3185 |       Dim = Value.getLimitedValue(); | 
| John Wiegley | cf56641 | 2011-04-28 02:06:46 +0000 | [diff] [blame] | 3186 |     } else { | 
 | 3187 |       Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer) << | 
 | 3188 |         DimExpr->getSourceRange(); | 
 | 3189 |       return false; | 
 | 3190 |     } | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3191 |  | 
 | 3192 |     if (T->isArrayType()) { | 
 | 3193 |       unsigned D = 0; | 
 | 3194 |       bool Matched = false; | 
 | 3195 |       while (const ArrayType *AT = Self.Context.getAsArrayType(T)) { | 
 | 3196 |         if (Dim == D) { | 
 | 3197 |           Matched = true; | 
 | 3198 |           break; | 
 | 3199 |         } | 
 | 3200 |         ++D; | 
 | 3201 |         T = AT->getElementType(); | 
 | 3202 |       } | 
 | 3203 |  | 
| John Wiegley | cf56641 | 2011-04-28 02:06:46 +0000 | [diff] [blame] | 3204 |       if (Matched && T->isArrayType()) { | 
 | 3205 |         if (const ConstantArrayType *CAT = Self.Context.getAsConstantArrayType(T)) | 
 | 3206 |           return CAT->getSize().getLimitedValue(); | 
 | 3207 |       } | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3208 |     } | 
| John Wiegley | cf56641 | 2011-04-28 02:06:46 +0000 | [diff] [blame] | 3209 |     return 0; | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3210 |   } | 
 | 3211 |   } | 
 | 3212 |   llvm_unreachable("Unknown type trait or not implemented"); | 
 | 3213 | } | 
 | 3214 |  | 
 | 3215 | ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT, | 
 | 3216 |                                      SourceLocation KWLoc, | 
 | 3217 |                                      TypeSourceInfo *TSInfo, | 
 | 3218 |                                      Expr* DimExpr, | 
 | 3219 |                                      SourceLocation RParen) { | 
 | 3220 |   QualType T = TSInfo->getType(); | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3221 |  | 
| Chandler Carruth | af5a3c6 | 2011-05-01 08:48:21 +0000 | [diff] [blame] | 3222 |   // FIXME: This should likely be tracked as an APInt to remove any host | 
 | 3223 |   // assumptions about the width of size_t on the target. | 
| Chandler Carruth | d064c70 | 2011-05-01 08:41:10 +0000 | [diff] [blame] | 3224 |   uint64_t Value = 0; | 
 | 3225 |   if (!T->isDependentType()) | 
 | 3226 |     Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc); | 
 | 3227 |  | 
| Chandler Carruth | af5a3c6 | 2011-05-01 08:48:21 +0000 | [diff] [blame] | 3228 |   // While the specification for these traits from the Embarcadero C++ | 
 | 3229 |   // compiler's documentation says the return type is 'unsigned int', Clang | 
 | 3230 |   // returns 'size_t'. On Windows, the primary platform for the Embarcadero | 
 | 3231 |   // compiler, there is no difference. On several other platforms this is an | 
 | 3232 |   // important distinction. | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3233 |   return Owned(new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, | 
| Chandler Carruth | 06207f6 | 2011-05-01 07:49:26 +0000 | [diff] [blame] | 3234 |                                                 DimExpr, RParen, | 
| Chandler Carruth | af5a3c6 | 2011-05-01 08:48:21 +0000 | [diff] [blame] | 3235 |                                                 Context.getSizeType())); | 
| John Wiegley | 21ff2e5 | 2011-04-28 00:16:57 +0000 | [diff] [blame] | 3236 | } | 
 | 3237 |  | 
| John Wiegley | 5526220 | 2011-04-25 06:54:41 +0000 | [diff] [blame] | 3238 | ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET, | 
| Chandler Carruth | 4aa0af3 | 2011-05-01 07:44:20 +0000 | [diff] [blame] | 3239 |                                       SourceLocation KWLoc, | 
 | 3240 |                                       Expr *Queried, | 
 | 3241 |                                       SourceLocation RParen) { | 
| John Wiegley | 5526220 | 2011-04-25 06:54:41 +0000 | [diff] [blame] | 3242 |   // If error parsing the expression, ignore. | 
 | 3243 |   if (!Queried) | 
| Chandler Carruth | 4aa0af3 | 2011-05-01 07:44:20 +0000 | [diff] [blame] | 3244 |     return ExprError(); | 
| John Wiegley | 5526220 | 2011-04-25 06:54:41 +0000 | [diff] [blame] | 3245 |  | 
| Chandler Carruth | 4aa0af3 | 2011-05-01 07:44:20 +0000 | [diff] [blame] | 3246 |   ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen); | 
| John Wiegley | 5526220 | 2011-04-25 06:54:41 +0000 | [diff] [blame] | 3247 |  | 
 | 3248 |   return move(Result); | 
 | 3249 | } | 
 | 3250 |  | 
| Chandler Carruth | 4aa0af3 | 2011-05-01 07:44:20 +0000 | [diff] [blame] | 3251 | static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E) { | 
 | 3252 |   switch (ET) { | 
 | 3253 |   case ET_IsLValueExpr: return E->isLValue(); | 
 | 3254 |   case ET_IsRValueExpr: return E->isRValue(); | 
 | 3255 |   } | 
 | 3256 |   llvm_unreachable("Expression trait not covered by switch"); | 
 | 3257 | } | 
 | 3258 |  | 
| John Wiegley | 5526220 | 2011-04-25 06:54:41 +0000 | [diff] [blame] | 3259 | ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET, | 
| Chandler Carruth | 4aa0af3 | 2011-05-01 07:44:20 +0000 | [diff] [blame] | 3260 |                                       SourceLocation KWLoc, | 
 | 3261 |                                       Expr *Queried, | 
 | 3262 |                                       SourceLocation RParen) { | 
| John Wiegley | 5526220 | 2011-04-25 06:54:41 +0000 | [diff] [blame] | 3263 |   if (Queried->isTypeDependent()) { | 
 | 3264 |     // Delay type-checking for type-dependent expressions. | 
 | 3265 |   } else if (Queried->getType()->isPlaceholderType()) { | 
 | 3266 |     ExprResult PE = CheckPlaceholderExpr(Queried); | 
 | 3267 |     if (PE.isInvalid()) return ExprError(); | 
 | 3268 |     return BuildExpressionTrait(ET, KWLoc, PE.take(), RParen); | 
 | 3269 |   } | 
 | 3270 |  | 
| Chandler Carruth | 4aa0af3 | 2011-05-01 07:44:20 +0000 | [diff] [blame] | 3271 |   bool Value = EvaluateExpressionTrait(ET, Queried); | 
| Chandler Carruth | f7ef000 | 2011-05-01 08:48:19 +0000 | [diff] [blame] | 3272 |  | 
| Chandler Carruth | 4aa0af3 | 2011-05-01 07:44:20 +0000 | [diff] [blame] | 3273 |   return Owned(new (Context) ExpressionTraitExpr(KWLoc, ET, Queried, Value, | 
 | 3274 |                                                  RParen, Context.BoolTy)); | 
| John Wiegley | 5526220 | 2011-04-25 06:54:41 +0000 | [diff] [blame] | 3275 | } | 
 | 3276 |  | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3277 | QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3278 |                                             ExprValueKind &VK, | 
 | 3279 |                                             SourceLocation Loc, | 
 | 3280 |                                             bool isIndirect) { | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3281 |   assert(!LHS.get()->getType()->isPlaceholderType() && | 
 | 3282 |          !RHS.get()->getType()->isPlaceholderType() && | 
| John McCall | ea4aba0 | 2011-06-30 17:15:34 +0000 | [diff] [blame] | 3283 |          "placeholders should have been weeded out by now"); | 
 | 3284 |  | 
 | 3285 |   // The LHS undergoes lvalue conversions if this is ->*. | 
 | 3286 |   if (isIndirect) { | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3287 |     LHS = DefaultLvalueConversion(LHS.take()); | 
 | 3288 |     if (LHS.isInvalid()) return QualType(); | 
| John McCall | ea4aba0 | 2011-06-30 17:15:34 +0000 | [diff] [blame] | 3289 |   } | 
 | 3290 |  | 
 | 3291 |   // The RHS always undergoes lvalue conversions. | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3292 |   RHS = DefaultLvalueConversion(RHS.take()); | 
 | 3293 |   if (RHS.isInvalid()) return QualType(); | 
| John McCall | ea4aba0 | 2011-06-30 17:15:34 +0000 | [diff] [blame] | 3294 |  | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3295 |   const char *OpSpelling = isIndirect ? "->*" : ".*"; | 
 | 3296 |   // C++ 5.5p2 | 
 | 3297 |   //   The binary operator .* [p3: ->*] binds its second operand, which shall | 
 | 3298 |   //   be of type "pointer to member of T" (where T is a completely-defined | 
 | 3299 |   //   class type) [...] | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3300 |   QualType RHSType = RHS.get()->getType(); | 
 | 3301 |   const MemberPointerType *MemPtr = RHSType->getAs<MemberPointerType>(); | 
| Douglas Gregor | e7450f5 | 2009-03-24 19:52:54 +0000 | [diff] [blame] | 3302 |   if (!MemPtr) { | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3303 |     Diag(Loc, diag::err_bad_memptr_rhs) | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3304 |       << OpSpelling << RHSType << RHS.get()->getSourceRange(); | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3305 |     return QualType(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3306 |   } | 
| Douglas Gregor | e7450f5 | 2009-03-24 19:52:54 +0000 | [diff] [blame] | 3307 |  | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3308 |   QualType Class(MemPtr->getClass(), 0); | 
 | 3309 |  | 
| Douglas Gregor | 7d520ba | 2010-10-13 20:41:14 +0000 | [diff] [blame] | 3310 |   // Note: C++ [expr.mptr.oper]p2-3 says that the class type into which the | 
 | 3311 |   // member pointer points must be completely-defined. However, there is no | 
 | 3312 |   // reason for this semantic distinction, and the rule is not enforced by | 
 | 3313 |   // other compilers. Therefore, we do not check this property, as it is | 
 | 3314 |   // likely to be considered a defect. | 
| Sebastian Redl | 59fc269 | 2010-04-10 10:14:54 +0000 | [diff] [blame] | 3315 |  | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3316 |   // C++ 5.5p2 | 
 | 3317 |   //   [...] to its first operand, which shall be of class T or of a class of | 
 | 3318 |   //   which T is an unambiguous and accessible base class. [p3: a pointer to | 
 | 3319 |   //   such a class] | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3320 |   QualType LHSType = LHS.get()->getType(); | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3321 |   if (isIndirect) { | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3322 |     if (const PointerType *Ptr = LHSType->getAs<PointerType>()) | 
 | 3323 |       LHSType = Ptr->getPointeeType(); | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3324 |     else { | 
 | 3325 |       Diag(Loc, diag::err_bad_memptr_lhs) | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3326 |         << OpSpelling << 1 << LHSType | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 3327 |         << FixItHint::CreateReplacement(SourceRange(Loc), ".*"); | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3328 |       return QualType(); | 
 | 3329 |     } | 
 | 3330 |   } | 
 | 3331 |  | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3332 |   if (!Context.hasSameUnqualifiedType(Class, LHSType)) { | 
| Sebastian Redl | 17e1d35 | 2010-04-23 17:18:26 +0000 | [diff] [blame] | 3333 |     // If we want to check the hierarchy, we need a complete type. | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3334 |     if (RequireCompleteType(Loc, LHSType, PDiag(diag::err_bad_memptr_lhs) | 
| Sebastian Redl | 17e1d35 | 2010-04-23 17:18:26 +0000 | [diff] [blame] | 3335 |         << OpSpelling << (int)isIndirect)) { | 
 | 3336 |       return QualType(); | 
 | 3337 |     } | 
| Anders Carlsson | 5cf86ba | 2010-04-24 19:06:50 +0000 | [diff] [blame] | 3338 |     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, | 
| Douglas Gregor | a8f32e0 | 2009-10-06 17:59:45 +0000 | [diff] [blame] | 3339 |                        /*DetectVirtual=*/false); | 
| Mike Stump | 390b4cc | 2009-05-16 07:39:55 +0000 | [diff] [blame] | 3340 |     // FIXME: Would it be useful to print full ambiguity paths, or is that | 
 | 3341 |     // overkill? | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3342 |     if (!IsDerivedFrom(LHSType, Class, Paths) || | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3343 |         Paths.isAmbiguous(Context.getCanonicalType(Class))) { | 
 | 3344 |       Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3345 |         << (int)isIndirect << LHS.get()->getType(); | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3346 |       return QualType(); | 
 | 3347 |     } | 
| Eli Friedman | 3005efe | 2010-01-16 00:00:48 +0000 | [diff] [blame] | 3348 |     // Cast LHS to type of use. | 
 | 3349 |     QualType UseType = isIndirect ? Context.getPointerType(Class) : Class; | 
| Eli Friedman | c1c0dfb | 2011-09-27 21:58:52 +0000 | [diff] [blame] | 3350 |     ExprValueKind VK = isIndirect ? VK_RValue : LHS.get()->getValueKind(); | 
| Sebastian Redl | 906082e | 2010-07-20 04:20:21 +0000 | [diff] [blame] | 3351 |  | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 3352 |     CXXCastPath BasePath; | 
| Anders Carlsson | 5cf86ba | 2010-04-24 19:06:50 +0000 | [diff] [blame] | 3353 |     BuildBasePathArray(Paths, BasePath); | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3354 |     LHS = ImpCastExprToType(LHS.take(), UseType, CK_DerivedToBase, VK, | 
 | 3355 |                             &BasePath); | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3356 |   } | 
 | 3357 |  | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3358 |   if (isa<CXXScalarValueInitExpr>(RHS.get()->IgnoreParens())) { | 
| Fariborz Jahanian | 05ebda9 | 2009-11-18 21:54:48 +0000 | [diff] [blame] | 3359 |     // Diagnose use of pointer-to-member type which when used as | 
 | 3360 |     // the functional cast in a pointer-to-member expression. | 
 | 3361 |     Diag(Loc, diag::err_pointer_to_member_type) << isIndirect; | 
 | 3362 |      return QualType(); | 
 | 3363 |   } | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3364 |  | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3365 |   // C++ 5.5p2 | 
 | 3366 |   //   The result is an object or a function of the type specified by the | 
 | 3367 |   //   second operand. | 
 | 3368 |   // The cv qualifiers are the union of those in the pointer and the left side, | 
 | 3369 |   // in accordance with 5.5p5 and 5.2.5. | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3370 |   QualType Result = MemPtr->getPointeeType(); | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3371 |   Result = Context.getCVRQualifiedType(Result, LHSType.getCVRQualifiers()); | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3372 |  | 
| Douglas Gregor | 6b4df91 | 2011-01-26 16:40:18 +0000 | [diff] [blame] | 3373 |   // C++0x [expr.mptr.oper]p6: | 
 | 3374 |   //   In a .* expression whose object expression is an rvalue, the program is | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3375 |   //   ill-formed if the second operand is a pointer to member function with | 
 | 3376 |   //   ref-qualifier &. In a ->* expression or in a .* expression whose object | 
 | 3377 |   //   expression is an lvalue, the program is ill-formed if the second operand | 
| Douglas Gregor | 6b4df91 | 2011-01-26 16:40:18 +0000 | [diff] [blame] | 3378 |   //   is a pointer to member function with ref-qualifier &&. | 
 | 3379 |   if (const FunctionProtoType *Proto = Result->getAs<FunctionProtoType>()) { | 
 | 3380 |     switch (Proto->getRefQualifier()) { | 
 | 3381 |     case RQ_None: | 
 | 3382 |       // Do nothing | 
 | 3383 |       break; | 
 | 3384 |  | 
 | 3385 |     case RQ_LValue: | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3386 |       if (!isIndirect && !LHS.get()->Classify(Context).isLValue()) | 
| Douglas Gregor | 6b4df91 | 2011-01-26 16:40:18 +0000 | [diff] [blame] | 3387 |         Diag(Loc, diag::err_pointer_to_member_oper_value_classify) | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3388 |           << RHSType << 1 << LHS.get()->getSourceRange(); | 
| Douglas Gregor | 6b4df91 | 2011-01-26 16:40:18 +0000 | [diff] [blame] | 3389 |       break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3390 |  | 
| Douglas Gregor | 6b4df91 | 2011-01-26 16:40:18 +0000 | [diff] [blame] | 3391 |     case RQ_RValue: | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3392 |       if (isIndirect || !LHS.get()->Classify(Context).isRValue()) | 
| Douglas Gregor | 6b4df91 | 2011-01-26 16:40:18 +0000 | [diff] [blame] | 3393 |         Diag(Loc, diag::err_pointer_to_member_oper_value_classify) | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3394 |           << RHSType << 0 << LHS.get()->getSourceRange(); | 
| Douglas Gregor | 6b4df91 | 2011-01-26 16:40:18 +0000 | [diff] [blame] | 3395 |       break; | 
 | 3396 |     } | 
 | 3397 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3398 |  | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3399 |   // C++ [expr.mptr.oper]p6: | 
 | 3400 |   //   The result of a .* expression whose second operand is a pointer | 
 | 3401 |   //   to a data member is of the same value category as its | 
 | 3402 |   //   first operand. The result of a .* expression whose second | 
 | 3403 |   //   operand is a pointer to a member function is a prvalue. The | 
 | 3404 |   //   result of an ->* expression is an lvalue if its second operand | 
 | 3405 |   //   is a pointer to data member and a prvalue otherwise. | 
| John McCall | 864c041 | 2011-04-26 20:42:42 +0000 | [diff] [blame] | 3406 |   if (Result->isFunctionType()) { | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3407 |     VK = VK_RValue; | 
| John McCall | 864c041 | 2011-04-26 20:42:42 +0000 | [diff] [blame] | 3408 |     return Context.BoundMemberTy; | 
 | 3409 |   } else if (isIndirect) { | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3410 |     VK = VK_LValue; | 
| John McCall | 864c041 | 2011-04-26 20:42:42 +0000 | [diff] [blame] | 3411 |   } else { | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3412 |     VK = LHS.get()->getValueKind(); | 
| John McCall | 864c041 | 2011-04-26 20:42:42 +0000 | [diff] [blame] | 3413 |   } | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3414 |  | 
| Sebastian Redl | 7c8bd60 | 2009-02-07 20:10:22 +0000 | [diff] [blame] | 3415 |   return Result; | 
 | 3416 | } | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3417 |  | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3418 | /// \brief Try to convert a type to another according to C++0x 5.16p3. | 
 | 3419 | /// | 
 | 3420 | /// This is part of the parameter validation for the ? operator. If either | 
 | 3421 | /// value operand is a class type, the two operands are attempted to be | 
 | 3422 | /// converted to each other. This function does the conversion in one direction. | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3423 | /// It returns true if the program is ill-formed and has already been diagnosed | 
 | 3424 | /// as such. | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3425 | static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, | 
 | 3426 |                                 SourceLocation QuestionLoc, | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3427 |                                 bool &HaveConversion, | 
 | 3428 |                                 QualType &ToType) { | 
 | 3429 |   HaveConversion = false; | 
 | 3430 |   ToType = To->getType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3431 |  | 
 | 3432 |   InitializationKind Kind = InitializationKind::CreateCopy(To->getLocStart(), | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3433 |                                                            SourceLocation()); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3434 |   // C++0x 5.16p3 | 
 | 3435 |   //   The process for determining whether an operand expression E1 of type T1 | 
 | 3436 |   //   can be converted to match an operand expression E2 of type T2 is defined | 
 | 3437 |   //   as follows: | 
 | 3438 |   //   -- If E2 is an lvalue: | 
| John McCall | 7eb0a9e | 2010-11-24 05:12:34 +0000 | [diff] [blame] | 3439 |   bool ToIsLvalue = To->isLValue(); | 
| Douglas Gregor | 0fd8ff7 | 2010-03-26 20:59:55 +0000 | [diff] [blame] | 3440 |   if (ToIsLvalue) { | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3441 |     //   E1 can be converted to match E2 if E1 can be implicitly converted to | 
 | 3442 |     //   type "lvalue reference to T2", subject to the constraint that in the | 
 | 3443 |     //   conversion the reference must bind directly to E1. | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3444 |     QualType T = Self.Context.getLValueReferenceType(ToType); | 
 | 3445 |     InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3446 |  | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3447 |     InitializationSequence InitSeq(Self, Entity, Kind, &From, 1); | 
 | 3448 |     if (InitSeq.isDirectReferenceBinding()) { | 
 | 3449 |       ToType = T; | 
 | 3450 |       HaveConversion = true; | 
 | 3451 |       return false; | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3452 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3453 |  | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3454 |     if (InitSeq.isAmbiguous()) | 
 | 3455 |       return InitSeq.Diagnose(Self, Entity, Kind, &From, 1); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3456 |   } | 
| John McCall | b1bdc62 | 2010-02-25 01:37:24 +0000 | [diff] [blame] | 3457 |  | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3458 |   //   -- If E2 is an rvalue, or if the conversion above cannot be done: | 
 | 3459 |   //      -- if E1 and E2 have class type, and the underlying class types are | 
 | 3460 |   //         the same or one is a base class of the other: | 
 | 3461 |   QualType FTy = From->getType(); | 
 | 3462 |   QualType TTy = To->getType(); | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 3463 |   const RecordType *FRec = FTy->getAs<RecordType>(); | 
 | 3464 |   const RecordType *TRec = TTy->getAs<RecordType>(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3465 |   bool FDerivedFromT = FRec && TRec && FRec != TRec && | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3466 |                        Self.IsDerivedFrom(FTy, TTy); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3467 |   if (FRec && TRec && | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3468 |       (FRec == TRec || FDerivedFromT || Self.IsDerivedFrom(TTy, FTy))) { | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3469 |     //         E1 can be converted to match E2 if the class of T2 is the | 
 | 3470 |     //         same type as, or a base class of, the class of T1, and | 
 | 3471 |     //         [cv2 > cv1]. | 
| John McCall | b1bdc62 | 2010-02-25 01:37:24 +0000 | [diff] [blame] | 3472 |     if (FRec == TRec || FDerivedFromT) { | 
 | 3473 |       if (TTy.isAtLeastAsQualifiedAs(FTy)) { | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3474 |         InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy); | 
 | 3475 |         InitializationSequence InitSeq(Self, Entity, Kind, &From, 1); | 
| Sebastian Redl | 383616c | 2011-06-05 12:23:28 +0000 | [diff] [blame] | 3476 |         if (InitSeq) { | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3477 |           HaveConversion = true; | 
 | 3478 |           return false; | 
 | 3479 |         } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3480 |  | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3481 |         if (InitSeq.isAmbiguous()) | 
 | 3482 |           return InitSeq.Diagnose(Self, Entity, Kind, &From, 1); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3483 |       } | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3484 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3485 |  | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3486 |     return false; | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3487 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3488 |  | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3489 |   //     -- Otherwise: E1 can be converted to match E2 if E1 can be | 
 | 3490 |   //        implicitly converted to the type that expression E2 would have | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3491 |   //        if E2 were converted to an rvalue (or the type it has, if E2 is | 
| Douglas Gregor | 0fd8ff7 | 2010-03-26 20:59:55 +0000 | [diff] [blame] | 3492 |   //        an rvalue). | 
 | 3493 |   // | 
 | 3494 |   // This actually refers very narrowly to the lvalue-to-rvalue conversion, not | 
 | 3495 |   // to the array-to-pointer or function-to-pointer conversions. | 
 | 3496 |   if (!TTy->getAs<TagType>()) | 
 | 3497 |     TTy = TTy.getUnqualifiedType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3498 |  | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3499 |   InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy); | 
 | 3500 |   InitializationSequence InitSeq(Self, Entity, Kind, &From, 1); | 
| Sebastian Redl | 383616c | 2011-06-05 12:23:28 +0000 | [diff] [blame] | 3501 |   HaveConversion = !InitSeq.Failed(); | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3502 |   ToType = TTy; | 
 | 3503 |   if (InitSeq.isAmbiguous()) | 
 | 3504 |     return InitSeq.Diagnose(Self, Entity, Kind, &From, 1); | 
 | 3505 |  | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3506 |   return false; | 
 | 3507 | } | 
 | 3508 |  | 
 | 3509 | /// \brief Try to find a common type for two according to C++0x 5.16p5. | 
 | 3510 | /// | 
 | 3511 | /// This is part of the parameter validation for the ? operator. If either | 
 | 3512 | /// value operand is a class type, overload resolution is used to find a | 
 | 3513 | /// conversion to a common type. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3514 | static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS, | 
| Chandler Carruth | 82214a8 | 2011-02-18 23:54:50 +0000 | [diff] [blame] | 3515 |                                     SourceLocation QuestionLoc) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3516 |   Expr *Args[2] = { LHS.get(), RHS.get() }; | 
| Chandler Carruth | 82214a8 | 2011-02-18 23:54:50 +0000 | [diff] [blame] | 3517 |   OverloadCandidateSet CandidateSet(QuestionLoc); | 
 | 3518 |   Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args, 2, | 
 | 3519 |                                     CandidateSet); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3520 |  | 
 | 3521 |   OverloadCandidateSet::iterator Best; | 
| Chandler Carruth | 82214a8 | 2011-02-18 23:54:50 +0000 | [diff] [blame] | 3522 |   switch (CandidateSet.BestViableFunction(Self, QuestionLoc, Best)) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3523 |     case OR_Success: { | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3524 |       // We found a match. Perform the conversions on the arguments and move on. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3525 |       ExprResult LHSRes = | 
 | 3526 |         Self.PerformImplicitConversion(LHS.get(), Best->BuiltinTypes.ParamTypes[0], | 
 | 3527 |                                        Best->Conversions[0], Sema::AA_Converting); | 
 | 3528 |       if (LHSRes.isInvalid()) | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3529 |         break; | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3530 |       LHS = move(LHSRes); | 
 | 3531 |  | 
 | 3532 |       ExprResult RHSRes = | 
 | 3533 |         Self.PerformImplicitConversion(RHS.get(), Best->BuiltinTypes.ParamTypes[1], | 
 | 3534 |                                        Best->Conversions[1], Sema::AA_Converting); | 
 | 3535 |       if (RHSRes.isInvalid()) | 
 | 3536 |         break; | 
 | 3537 |       RHS = move(RHSRes); | 
| Chandler Carruth | 25ca421 | 2011-02-25 19:41:05 +0000 | [diff] [blame] | 3538 |       if (Best->Function) | 
 | 3539 |         Self.MarkDeclarationReferenced(QuestionLoc, Best->Function); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3540 |       return false; | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3541 |     } | 
 | 3542 |      | 
| Douglas Gregor | 20093b4 | 2009-12-09 23:02:17 +0000 | [diff] [blame] | 3543 |     case OR_No_Viable_Function: | 
| Chandler Carruth | 82214a8 | 2011-02-18 23:54:50 +0000 | [diff] [blame] | 3544 |  | 
 | 3545 |       // Emit a better diagnostic if one of the expressions is a null pointer | 
 | 3546 |       // constant and the other is a pointer type. In this case, the user most | 
 | 3547 |       // likely forgot to take the address of the other expression. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3548 |       if (Self.DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc)) | 
| Chandler Carruth | 82214a8 | 2011-02-18 23:54:50 +0000 | [diff] [blame] | 3549 |         return true; | 
 | 3550 |  | 
 | 3551 |       Self.Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3552 |         << LHS.get()->getType() << RHS.get()->getType() | 
 | 3553 |         << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3554 |       return true; | 
 | 3555 |  | 
| Douglas Gregor | 20093b4 | 2009-12-09 23:02:17 +0000 | [diff] [blame] | 3556 |     case OR_Ambiguous: | 
| Chandler Carruth | 82214a8 | 2011-02-18 23:54:50 +0000 | [diff] [blame] | 3557 |       Self.Diag(QuestionLoc, diag::err_conditional_ambiguous_ovl) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3558 |         << LHS.get()->getType() << RHS.get()->getType() | 
 | 3559 |         << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); | 
| Mike Stump | 390b4cc | 2009-05-16 07:39:55 +0000 | [diff] [blame] | 3560 |       // FIXME: Print the possible common types by printing the return types of | 
 | 3561 |       // the viable candidates. | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3562 |       break; | 
 | 3563 |  | 
| Douglas Gregor | 20093b4 | 2009-12-09 23:02:17 +0000 | [diff] [blame] | 3564 |     case OR_Deleted: | 
| David Blaikie | b219cfc | 2011-09-23 05:06:16 +0000 | [diff] [blame] | 3565 |       llvm_unreachable("Conditional operator has only built-in overloads"); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3566 |   } | 
 | 3567 |   return true; | 
 | 3568 | } | 
 | 3569 |  | 
| Sebastian Redl | 7645850 | 2009-04-17 16:30:52 +0000 | [diff] [blame] | 3570 | /// \brief Perform an "extended" implicit conversion as returned by | 
 | 3571 | /// TryClassUnification. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3572 | static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) { | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3573 |   InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3574 |   InitializationKind Kind = InitializationKind::CreateCopy(E.get()->getLocStart(), | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3575 |                                                            SourceLocation()); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3576 |   Expr *Arg = E.take(); | 
 | 3577 |   InitializationSequence InitSeq(Self, Entity, Kind, &Arg, 1); | 
 | 3578 |   ExprResult Result = InitSeq.Perform(Self, Entity, Kind, MultiExprArg(&Arg, 1)); | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3579 |   if (Result.isInvalid()) | 
| Sebastian Redl | 7645850 | 2009-04-17 16:30:52 +0000 | [diff] [blame] | 3580 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3581 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3582 |   E = Result; | 
| Sebastian Redl | 7645850 | 2009-04-17 16:30:52 +0000 | [diff] [blame] | 3583 |   return false; | 
 | 3584 | } | 
 | 3585 |  | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3586 | /// \brief Check the operands of ?: under C++ semantics. | 
 | 3587 | /// | 
 | 3588 | /// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y | 
 | 3589 | /// extension. In this case, LHS == Cond. (But they're not aliases.) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3590 | QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 3591 |                                            ExprValueKind &VK, ExprObjectKind &OK, | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3592 |                                            SourceLocation QuestionLoc) { | 
| Mike Stump | 390b4cc | 2009-05-16 07:39:55 +0000 | [diff] [blame] | 3593 |   // FIXME: Handle C99's complex types, vector types, block pointers and Obj-C++ | 
 | 3594 |   // interface pointers. | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3595 |  | 
 | 3596 |   // C++0x 5.16p1 | 
 | 3597 |   //   The first expression is contextually converted to bool. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3598 |   if (!Cond.get()->isTypeDependent()) { | 
 | 3599 |     ExprResult CondRes = CheckCXXBooleanCondition(Cond.take()); | 
 | 3600 |     if (CondRes.isInvalid()) | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3601 |       return QualType(); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3602 |     Cond = move(CondRes); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3603 |   } | 
 | 3604 |  | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3605 |   // Assume r-value. | 
 | 3606 |   VK = VK_RValue; | 
| John McCall | 0943168 | 2010-11-18 19:01:18 +0000 | [diff] [blame] | 3607 |   OK = OK_Ordinary; | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3608 |  | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3609 |   // Either of the arguments dependent? | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3610 |   if (LHS.get()->isTypeDependent() || RHS.get()->isTypeDependent()) | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3611 |     return Context.DependentTy; | 
 | 3612 |  | 
 | 3613 |   // C++0x 5.16p2 | 
 | 3614 |   //   If either the second or the third operand has type (cv) void, ... | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3615 |   QualType LTy = LHS.get()->getType(); | 
 | 3616 |   QualType RTy = RHS.get()->getType(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3617 |   bool LVoid = LTy->isVoidType(); | 
 | 3618 |   bool RVoid = RTy->isVoidType(); | 
 | 3619 |   if (LVoid || RVoid) { | 
 | 3620 |     //   ... then the [l2r] conversions are performed on the second and third | 
 | 3621 |     //   operands ... | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3622 |     LHS = DefaultFunctionArrayLvalueConversion(LHS.take()); | 
 | 3623 |     RHS = DefaultFunctionArrayLvalueConversion(RHS.take()); | 
 | 3624 |     if (LHS.isInvalid() || RHS.isInvalid()) | 
 | 3625 |       return QualType(); | 
 | 3626 |     LTy = LHS.get()->getType(); | 
 | 3627 |     RTy = RHS.get()->getType(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3628 |  | 
 | 3629 |     //   ... and one of the following shall hold: | 
 | 3630 |     //   -- The second or the third operand (but not both) is a throw- | 
 | 3631 |     //      expression; the result is of the type of the other and is an rvalue. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3632 |     bool LThrow = isa<CXXThrowExpr>(LHS.get()); | 
 | 3633 |     bool RThrow = isa<CXXThrowExpr>(RHS.get()); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3634 |     if (LThrow && !RThrow) | 
 | 3635 |       return RTy; | 
 | 3636 |     if (RThrow && !LThrow) | 
 | 3637 |       return LTy; | 
 | 3638 |  | 
 | 3639 |     //   -- Both the second and third operands have type void; the result is of | 
 | 3640 |     //      type void and is an rvalue. | 
 | 3641 |     if (LVoid && RVoid) | 
 | 3642 |       return Context.VoidTy; | 
 | 3643 |  | 
 | 3644 |     // Neither holds, error. | 
 | 3645 |     Diag(QuestionLoc, diag::err_conditional_void_nonvoid) | 
 | 3646 |       << (LVoid ? RTy : LTy) << (LVoid ? 0 : 1) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3647 |       << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3648 |     return QualType(); | 
 | 3649 |   } | 
 | 3650 |  | 
 | 3651 |   // Neither is void. | 
 | 3652 |  | 
 | 3653 |   // C++0x 5.16p3 | 
 | 3654 |   //   Otherwise, if the second and third operand have different types, and | 
 | 3655 |   //   either has (cv) class type, and attempt is made to convert each of those | 
 | 3656 |   //   operands to the other. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3657 |   if (!Context.hasSameType(LTy, RTy) && | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3658 |       (LTy->isRecordType() || RTy->isRecordType())) { | 
 | 3659 |     ImplicitConversionSequence ICSLeftToRight, ICSRightToLeft; | 
 | 3660 |     // These return true if a single direction is already ambiguous. | 
| Douglas Gregor | b70cf44 | 2010-03-26 20:14:36 +0000 | [diff] [blame] | 3661 |     QualType L2RType, R2LType; | 
 | 3662 |     bool HaveL2R, HaveR2L; | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3663 |     if (TryClassUnification(*this, LHS.get(), RHS.get(), QuestionLoc, HaveL2R, L2RType)) | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3664 |       return QualType(); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3665 |     if (TryClassUnification(*this, RHS.get(), LHS.get(), QuestionLoc, HaveR2L, R2LType)) | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3666 |       return QualType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3667 |  | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3668 |     //   If both can be converted, [...] the program is ill-formed. | 
 | 3669 |     if (HaveL2R && HaveR2L) { | 
 | 3670 |       Diag(QuestionLoc, diag::err_conditional_ambiguous) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3671 |         << LTy << RTy << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3672 |       return QualType(); | 
 | 3673 |     } | 
 | 3674 |  | 
 | 3675 |     //   If exactly one conversion is possible, that conversion is applied to | 
 | 3676 |     //   the chosen operand and the converted operands are used in place of the | 
 | 3677 |     //   original operands for the remainder of this section. | 
 | 3678 |     if (HaveL2R) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3679 |       if (ConvertForConditional(*this, LHS, L2RType) || LHS.isInvalid()) | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3680 |         return QualType(); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3681 |       LTy = LHS.get()->getType(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3682 |     } else if (HaveR2L) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3683 |       if (ConvertForConditional(*this, RHS, R2LType) || RHS.isInvalid()) | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3684 |         return QualType(); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3685 |       RTy = RHS.get()->getType(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3686 |     } | 
 | 3687 |   } | 
 | 3688 |  | 
 | 3689 |   // C++0x 5.16p4 | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3690 |   //   If the second and third operands are glvalues of the same value | 
 | 3691 |   //   category and have the same type, the result is of that type and | 
 | 3692 |   //   value category and it is a bit-field if the second or the third | 
 | 3693 |   //   operand is a bit-field, or if both are bit-fields. | 
| John McCall | 0943168 | 2010-11-18 19:01:18 +0000 | [diff] [blame] | 3694 |   // We only extend this to bitfields, not to the crazy other kinds of | 
 | 3695 |   // l-values. | 
| Douglas Gregor | 1927b1f | 2010-04-01 22:47:07 +0000 | [diff] [blame] | 3696 |   bool Same = Context.hasSameType(LTy, RTy); | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3697 |   if (Same && | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3698 |       LHS.get()->isGLValue() && | 
 | 3699 |       LHS.get()->getValueKind() == RHS.get()->getValueKind() && | 
 | 3700 |       LHS.get()->isOrdinaryOrBitFieldObject() && | 
 | 3701 |       RHS.get()->isOrdinaryOrBitFieldObject()) { | 
 | 3702 |     VK = LHS.get()->getValueKind(); | 
 | 3703 |     if (LHS.get()->getObjectKind() == OK_BitField || | 
 | 3704 |         RHS.get()->getObjectKind() == OK_BitField) | 
| John McCall | 0943168 | 2010-11-18 19:01:18 +0000 | [diff] [blame] | 3705 |       OK = OK_BitField; | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3706 |     return LTy; | 
| Fariborz Jahanian | 3911a1a | 2010-09-25 01:08:05 +0000 | [diff] [blame] | 3707 |   } | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3708 |  | 
 | 3709 |   // C++0x 5.16p5 | 
 | 3710 |   //   Otherwise, the result is an rvalue. If the second and third operands | 
 | 3711 |   //   do not have the same type, and either has (cv) class type, ... | 
 | 3712 |   if (!Same && (LTy->isRecordType() || RTy->isRecordType())) { | 
 | 3713 |     //   ... overload resolution is used to determine the conversions (if any) | 
 | 3714 |     //   to be applied to the operands. If the overload resolution fails, the | 
 | 3715 |     //   program is ill-formed. | 
 | 3716 |     if (FindConditionalOverload(*this, LHS, RHS, QuestionLoc)) | 
 | 3717 |       return QualType(); | 
 | 3718 |   } | 
 | 3719 |  | 
 | 3720 |   // C++0x 5.16p6 | 
 | 3721 |   //   LValue-to-rvalue, array-to-pointer, and function-to-pointer standard | 
 | 3722 |   //   conversions are performed on the second and third operands. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3723 |   LHS = DefaultFunctionArrayLvalueConversion(LHS.take()); | 
 | 3724 |   RHS = DefaultFunctionArrayLvalueConversion(RHS.take()); | 
 | 3725 |   if (LHS.isInvalid() || RHS.isInvalid()) | 
 | 3726 |     return QualType(); | 
 | 3727 |   LTy = LHS.get()->getType(); | 
 | 3728 |   RTy = RHS.get()->getType(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3729 |  | 
 | 3730 |   //   After those conversions, one of the following shall hold: | 
 | 3731 |   //   -- The second and third operands have the same type; the result | 
| Douglas Gregor | b65a458 | 2010-05-19 23:40:50 +0000 | [diff] [blame] | 3732 |   //      is of that type. If the operands have class type, the result | 
 | 3733 |   //      is a prvalue temporary of the result type, which is | 
 | 3734 |   //      copy-initialized from either the second operand or the third | 
 | 3735 |   //      operand depending on the value of the first operand. | 
 | 3736 |   if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) { | 
 | 3737 |     if (LTy->isRecordType()) { | 
 | 3738 |       // The operands have class type. Make a temporary copy. | 
 | 3739 |       InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3740 |       ExprResult LHSCopy = PerformCopyInitialization(Entity, | 
 | 3741 |                                                      SourceLocation(), | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3742 |                                                      LHS); | 
| Douglas Gregor | b65a458 | 2010-05-19 23:40:50 +0000 | [diff] [blame] | 3743 |       if (LHSCopy.isInvalid()) | 
 | 3744 |         return QualType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3745 |  | 
 | 3746 |       ExprResult RHSCopy = PerformCopyInitialization(Entity, | 
 | 3747 |                                                      SourceLocation(), | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3748 |                                                      RHS); | 
| Douglas Gregor | b65a458 | 2010-05-19 23:40:50 +0000 | [diff] [blame] | 3749 |       if (RHSCopy.isInvalid()) | 
 | 3750 |         return QualType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3751 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3752 |       LHS = LHSCopy; | 
 | 3753 |       RHS = RHSCopy; | 
| Douglas Gregor | b65a458 | 2010-05-19 23:40:50 +0000 | [diff] [blame] | 3754 |     } | 
 | 3755 |  | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3756 |     return LTy; | 
| Douglas Gregor | b65a458 | 2010-05-19 23:40:50 +0000 | [diff] [blame] | 3757 |   } | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3758 |  | 
| Douglas Gregor | fb4a543 | 2010-05-18 22:42:18 +0000 | [diff] [blame] | 3759 |   // Extension: conditional operator involving vector types. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3760 |   if (LTy->isVectorType() || RTy->isVectorType()) | 
| Eli Friedman | b9b4b78 | 2011-06-23 18:10:35 +0000 | [diff] [blame] | 3761 |     return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); | 
| Douglas Gregor | fb4a543 | 2010-05-18 22:42:18 +0000 | [diff] [blame] | 3762 |  | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3763 |   //   -- The second and third operands have arithmetic or enumeration type; | 
 | 3764 |   //      the usual arithmetic conversions are performed to bring them to a | 
 | 3765 |   //      common type, and the result is of that type. | 
 | 3766 |   if (LTy->isArithmeticType() && RTy->isArithmeticType()) { | 
 | 3767 |     UsualArithmeticConversions(LHS, RHS); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3768 |     if (LHS.isInvalid() || RHS.isInvalid()) | 
 | 3769 |       return QualType(); | 
 | 3770 |     return LHS.get()->getType(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3771 |   } | 
 | 3772 |  | 
 | 3773 |   //   -- The second and third operands have pointer type, or one has pointer | 
 | 3774 |   //      type and the other is a null pointer constant; pointer conversions | 
 | 3775 |   //      and qualification conversions are performed to bring them to their | 
 | 3776 |   //      composite pointer type. The result is of the composite pointer type. | 
| Eli Friedman | de8ac49 | 2010-01-02 22:56:07 +0000 | [diff] [blame] | 3777 |   //   -- The second and third operands have pointer to member type, or one has | 
 | 3778 |   //      pointer to member type and the other is a null pointer constant; | 
 | 3779 |   //      pointer to member conversions and qualification conversions are | 
 | 3780 |   //      performed to bring them to a common type, whose cv-qualification | 
 | 3781 |   //      shall match the cv-qualification of either the second or the third | 
 | 3782 |   //      operand. The result is of the common type. | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3783 |   bool NonStandardCompositeType = false; | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 3784 |   QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS, | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3785 |                               isSFINAEContext()? 0 : &NonStandardCompositeType); | 
 | 3786 |   if (!Composite.isNull()) { | 
 | 3787 |     if (NonStandardCompositeType) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3788 |       Diag(QuestionLoc, | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3789 |            diag::ext_typecheck_cond_incompatible_operands_nonstandard) | 
 | 3790 |         << LTy << RTy << Composite | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3791 |         << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3792 |  | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 3793 |     return Composite; | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3794 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3795 |  | 
| Douglas Gregor | 1927b1f | 2010-04-01 22:47:07 +0000 | [diff] [blame] | 3796 |   // Similarly, attempt to find composite type of two objective-c pointers. | 
| Fariborz Jahanian | 5501636 | 2009-12-10 20:46:08 +0000 | [diff] [blame] | 3797 |   Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc); | 
 | 3798 |   if (!Composite.isNull()) | 
 | 3799 |     return Composite; | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3800 |  | 
| Chandler Carruth | 7ef9324 | 2011-02-19 00:13:59 +0000 | [diff] [blame] | 3801 |   // Check if we are using a null with a non-pointer type. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3802 |   if (DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc)) | 
| Chandler Carruth | 7ef9324 | 2011-02-19 00:13:59 +0000 | [diff] [blame] | 3803 |     return QualType(); | 
 | 3804 |  | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3805 |   Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3806 |     << LHS.get()->getType() << RHS.get()->getType() | 
 | 3807 |     << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); | 
| Sebastian Redl | 3201f6b | 2009-04-16 17:51:27 +0000 | [diff] [blame] | 3808 |   return QualType(); | 
 | 3809 | } | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 3810 |  | 
 | 3811 | /// \brief Find a merged pointer type and convert the two expressions to it. | 
 | 3812 | /// | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3813 | /// This finds the composite pointer type (or member pointer type) for @p E1 | 
 | 3814 | /// and @p E2 according to C++0x 5.9p2. It converts both expressions to this | 
 | 3815 | /// type and returns it. | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 3816 | /// It does not emit diagnostics. | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3817 | /// | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 3818 | /// \param Loc The location of the operator requiring these two expressions to | 
 | 3819 | /// be converted to the composite pointer type. | 
 | 3820 | /// | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3821 | /// If \p NonStandardCompositeType is non-NULL, then we are permitted to find | 
 | 3822 | /// a non-standard (but still sane) composite type to which both expressions | 
 | 3823 | /// can be converted. When such a type is chosen, \c *NonStandardCompositeType | 
 | 3824 | /// will be set true. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3825 | QualType Sema::FindCompositePointerType(SourceLocation Loc, | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 3826 |                                         Expr *&E1, Expr *&E2, | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3827 |                                         bool *NonStandardCompositeType) { | 
 | 3828 |   if (NonStandardCompositeType) | 
 | 3829 |     *NonStandardCompositeType = false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3830 |  | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 3831 |   assert(getLangOptions().CPlusPlus && "This function assumes C++"); | 
 | 3832 |   QualType T1 = E1->getType(), T2 = E2->getType(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3833 |  | 
| Fariborz Jahanian | 0cedfbd | 2009-12-08 20:04:24 +0000 | [diff] [blame] | 3834 |   if (!T1->isAnyPointerType() && !T1->isMemberPointerType() && | 
 | 3835 |       !T2->isAnyPointerType() && !T2->isMemberPointerType()) | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3836 |    return QualType(); | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 3837 |  | 
 | 3838 |   // C++0x 5.9p2 | 
 | 3839 |   //   Pointer conversions and qualification conversions are performed on | 
 | 3840 |   //   pointer operands to bring them to their composite pointer type. If | 
 | 3841 |   //   one operand is a null pointer constant, the composite pointer type is | 
 | 3842 |   //   the type of the other operand. | 
| Douglas Gregor | ce94049 | 2009-09-25 04:25:58 +0000 | [diff] [blame] | 3843 |   if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 3844 |     if (T2->isMemberPointerType()) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3845 |       E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).take(); | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 3846 |     else | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3847 |       E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take(); | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 3848 |     return T2; | 
 | 3849 |   } | 
| Douglas Gregor | ce94049 | 2009-09-25 04:25:58 +0000 | [diff] [blame] | 3850 |   if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 3851 |     if (T1->isMemberPointerType()) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3852 |       E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).take(); | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 3853 |     else | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 3854 |       E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take(); | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 3855 |     return T1; | 
 | 3856 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3857 |  | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3858 |   // Now both have to be pointers or member pointers. | 
| Sebastian Redl | a439e6f | 2009-11-16 21:03:45 +0000 | [diff] [blame] | 3859 |   if ((!T1->isPointerType() && !T1->isMemberPointerType()) || | 
 | 3860 |       (!T2->isPointerType() && !T2->isMemberPointerType())) | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 3861 |     return QualType(); | 
 | 3862 |  | 
 | 3863 |   //   Otherwise, of one of the operands has type "pointer to cv1 void," then | 
 | 3864 |   //   the other has type "pointer to cv2 T" and the composite pointer type is | 
 | 3865 |   //   "pointer to cv12 void," where cv12 is the union of cv1 and cv2. | 
 | 3866 |   //   Otherwise, the composite pointer type is a pointer type similar to the | 
 | 3867 |   //   type of one of the operands, with a cv-qualification signature that is | 
 | 3868 |   //   the union of the cv-qualification signatures of the operand types. | 
 | 3869 |   // In practice, the first part here is redundant; it's subsumed by the second. | 
 | 3870 |   // What we do here is, we build the two possible composite types, and try the | 
 | 3871 |   // conversions in both directions. If only one works, or if the two composite | 
 | 3872 |   // types are the same, we have succeeded. | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 3873 |   // FIXME: extended qualifiers? | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 3874 |   typedef SmallVector<unsigned, 4> QualifierVector; | 
| Sebastian Redl | a439e6f | 2009-11-16 21:03:45 +0000 | [diff] [blame] | 3875 |   QualifierVector QualifierUnion; | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 3876 |   typedef SmallVector<std::pair<const Type *, const Type *>, 4> | 
| Sebastian Redl | a439e6f | 2009-11-16 21:03:45 +0000 | [diff] [blame] | 3877 |       ContainingClassVector; | 
 | 3878 |   ContainingClassVector MemberOfClass; | 
 | 3879 |   QualType Composite1 = Context.getCanonicalType(T1), | 
 | 3880 |            Composite2 = Context.getCanonicalType(T2); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3881 |   unsigned NeedConstBefore = 0; | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3882 |   do { | 
 | 3883 |     const PointerType *Ptr1, *Ptr2; | 
 | 3884 |     if ((Ptr1 = Composite1->getAs<PointerType>()) && | 
 | 3885 |         (Ptr2 = Composite2->getAs<PointerType>())) { | 
 | 3886 |       Composite1 = Ptr1->getPointeeType(); | 
 | 3887 |       Composite2 = Ptr2->getPointeeType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3888 |  | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3889 |       // If we're allowed to create a non-standard composite type, keep track | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3890 |       // of where we need to fill in additional 'const' qualifiers. | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3891 |       if (NonStandardCompositeType && | 
 | 3892 |           Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers()) | 
 | 3893 |         NeedConstBefore = QualifierUnion.size(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3894 |  | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3895 |       QualifierUnion.push_back( | 
 | 3896 |                  Composite1.getCVRQualifiers() | Composite2.getCVRQualifiers()); | 
 | 3897 |       MemberOfClass.push_back(std::make_pair((const Type *)0, (const Type *)0)); | 
 | 3898 |       continue; | 
 | 3899 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3900 |  | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3901 |     const MemberPointerType *MemPtr1, *MemPtr2; | 
 | 3902 |     if ((MemPtr1 = Composite1->getAs<MemberPointerType>()) && | 
 | 3903 |         (MemPtr2 = Composite2->getAs<MemberPointerType>())) { | 
 | 3904 |       Composite1 = MemPtr1->getPointeeType(); | 
 | 3905 |       Composite2 = MemPtr2->getPointeeType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3906 |  | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3907 |       // If we're allowed to create a non-standard composite type, keep track | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3908 |       // of where we need to fill in additional 'const' qualifiers. | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3909 |       if (NonStandardCompositeType && | 
 | 3910 |           Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers()) | 
 | 3911 |         NeedConstBefore = QualifierUnion.size(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3912 |  | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3913 |       QualifierUnion.push_back( | 
 | 3914 |                  Composite1.getCVRQualifiers() | Composite2.getCVRQualifiers()); | 
 | 3915 |       MemberOfClass.push_back(std::make_pair(MemPtr1->getClass(), | 
 | 3916 |                                              MemPtr2->getClass())); | 
 | 3917 |       continue; | 
 | 3918 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3919 |  | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3920 |     // FIXME: block pointer types? | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3921 |  | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3922 |     // Cannot unwrap any more types. | 
 | 3923 |     break; | 
 | 3924 |   } while (true); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3925 |  | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3926 |   if (NeedConstBefore && NonStandardCompositeType) { | 
 | 3927 |     // Extension: Add 'const' to qualifiers that come before the first qualifier | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3928 |     // mismatch, so that our (non-standard!) composite type meets the | 
| Douglas Gregor | b2cb1cb | 2010-02-25 22:29:57 +0000 | [diff] [blame] | 3929 |     // requirements of C++ [conv.qual]p4 bullet 3. | 
 | 3930 |     for (unsigned I = 0; I != NeedConstBefore; ++I) { | 
 | 3931 |       if ((QualifierUnion[I] & Qualifiers::Const) == 0) { | 
 | 3932 |         QualifierUnion[I] = QualifierUnion[I] | Qualifiers::Const; | 
 | 3933 |         *NonStandardCompositeType = true; | 
 | 3934 |       } | 
 | 3935 |     } | 
 | 3936 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3937 |  | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3938 |   // Rewrap the composites as pointers or member pointers with the union CVRs. | 
| Sebastian Redl | a439e6f | 2009-11-16 21:03:45 +0000 | [diff] [blame] | 3939 |   ContainingClassVector::reverse_iterator MOC | 
 | 3940 |     = MemberOfClass.rbegin(); | 
 | 3941 |   for (QualifierVector::reverse_iterator | 
 | 3942 |          I = QualifierUnion.rbegin(), | 
 | 3943 |          E = QualifierUnion.rend(); | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3944 |        I != E; (void)++I, ++MOC) { | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 3945 |     Qualifiers Quals = Qualifiers::fromCVRMask(*I); | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3946 |     if (MOC->first && MOC->second) { | 
 | 3947 |       // Rebuild member pointer type | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 3948 |       Composite1 = Context.getMemberPointerType( | 
 | 3949 |                                     Context.getQualifiedType(Composite1, Quals), | 
 | 3950 |                                     MOC->first); | 
 | 3951 |       Composite2 = Context.getMemberPointerType( | 
 | 3952 |                                     Context.getQualifiedType(Composite2, Quals), | 
 | 3953 |                                     MOC->second); | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3954 |     } else { | 
 | 3955 |       // Rebuild pointer type | 
| John McCall | 0953e76 | 2009-09-24 19:53:00 +0000 | [diff] [blame] | 3956 |       Composite1 | 
 | 3957 |         = Context.getPointerType(Context.getQualifiedType(Composite1, Quals)); | 
 | 3958 |       Composite2 | 
 | 3959 |         = Context.getPointerType(Context.getQualifiedType(Composite2, Quals)); | 
| Douglas Gregor | 20b3e99 | 2009-08-24 17:42:35 +0000 | [diff] [blame] | 3960 |     } | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 3961 |   } | 
 | 3962 |  | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 3963 |   // Try to convert to the first composite pointer type. | 
 | 3964 |   InitializedEntity Entity1 | 
 | 3965 |     = InitializedEntity::InitializeTemporary(Composite1); | 
 | 3966 |   InitializationKind Kind | 
 | 3967 |     = InitializationKind::CreateCopy(Loc, SourceLocation()); | 
 | 3968 |   InitializationSequence E1ToC1(*this, Entity1, Kind, &E1, 1); | 
 | 3969 |   InitializationSequence E2ToC1(*this, Entity1, Kind, &E2, 1); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3970 |  | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 3971 |   if (E1ToC1 && E2ToC1) { | 
 | 3972 |     // Conversion to Composite1 is viable. | 
 | 3973 |     if (!Context.hasSameType(Composite1, Composite2)) { | 
 | 3974 |       // Composite2 is a different type from Composite1. Check whether | 
 | 3975 |       // Composite2 is also viable. | 
 | 3976 |       InitializedEntity Entity2 | 
 | 3977 |         = InitializedEntity::InitializeTemporary(Composite2); | 
 | 3978 |       InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1); | 
 | 3979 |       InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1); | 
 | 3980 |       if (E1ToC2 && E2ToC2) { | 
 | 3981 |         // Both Composite1 and Composite2 are viable and are different; | 
 | 3982 |         // this is an ambiguity. | 
 | 3983 |         return QualType(); | 
 | 3984 |       } | 
 | 3985 |     } | 
 | 3986 |  | 
 | 3987 |     // Convert E1 to Composite1 | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 3988 |     ExprResult E1Result | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 3989 |       = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E1,1)); | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 3990 |     if (E1Result.isInvalid()) | 
 | 3991 |       return QualType(); | 
 | 3992 |     E1 = E1Result.takeAs<Expr>(); | 
 | 3993 |  | 
 | 3994 |     // Convert E2 to Composite1 | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 3995 |     ExprResult E2Result | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 3996 |       = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E2,1)); | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 3997 |     if (E2Result.isInvalid()) | 
 | 3998 |       return QualType(); | 
 | 3999 |     E2 = E2Result.takeAs<Expr>(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4000 |  | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 4001 |     return Composite1; | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 4002 |   } | 
 | 4003 |  | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 4004 |   // Check whether Composite2 is viable. | 
 | 4005 |   InitializedEntity Entity2 | 
 | 4006 |     = InitializedEntity::InitializeTemporary(Composite2); | 
 | 4007 |   InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1); | 
 | 4008 |   InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1); | 
 | 4009 |   if (!E1ToC2 || !E2ToC2) | 
 | 4010 |     return QualType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4011 |  | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 4012 |   // Convert E1 to Composite2 | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 4013 |   ExprResult E1Result | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 4014 |     = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E1, 1)); | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 4015 |   if (E1Result.isInvalid()) | 
 | 4016 |     return QualType(); | 
 | 4017 |   E1 = E1Result.takeAs<Expr>(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4018 |  | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 4019 |   // Convert E2 to Composite2 | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 4020 |   ExprResult E2Result | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 4021 |     = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E2, 1)); | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 4022 |   if (E2Result.isInvalid()) | 
 | 4023 |     return QualType(); | 
 | 4024 |   E2 = E2Result.takeAs<Expr>(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4025 |  | 
| Douglas Gregor | 8f00dcf | 2010-04-16 23:20:25 +0000 | [diff] [blame] | 4026 |   return Composite2; | 
| Sebastian Redl | d1bd7fc | 2009-04-19 19:26:31 +0000 | [diff] [blame] | 4027 | } | 
| Anders Carlsson | 165a0a0 | 2009-05-17 18:41:29 +0000 | [diff] [blame] | 4028 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 4029 | ExprResult Sema::MaybeBindToTemporary(Expr *E) { | 
| Douglas Gregor | 19cc1c7 | 2010-11-01 21:10:29 +0000 | [diff] [blame] | 4030 |   if (!E) | 
 | 4031 |     return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4032 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4033 |   assert(!isa<CXXBindTemporaryExpr>(E) && "Double-bound temporary?"); | 
 | 4034 |  | 
 | 4035 |   // If the result is a glvalue, we shouldn't bind it. | 
 | 4036 |   if (!E->isRValue()) | 
| Anders Carlsson | 089c260 | 2009-08-15 23:41:35 +0000 | [diff] [blame] | 4037 |     return Owned(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4038 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4039 |   // In ARC, calls that return a retainable type can return retained, | 
 | 4040 |   // in which case we have to insert a consuming cast. | 
 | 4041 |   if (getLangOptions().ObjCAutoRefCount && | 
 | 4042 |       E->getType()->isObjCRetainableType()) { | 
 | 4043 |  | 
 | 4044 |     bool ReturnsRetained; | 
 | 4045 |  | 
 | 4046 |     // For actual calls, we compute this by examining the type of the | 
 | 4047 |     // called value. | 
 | 4048 |     if (CallExpr *Call = dyn_cast<CallExpr>(E)) { | 
 | 4049 |       Expr *Callee = Call->getCallee()->IgnoreParens(); | 
 | 4050 |       QualType T = Callee->getType(); | 
 | 4051 |  | 
 | 4052 |       if (T == Context.BoundMemberTy) { | 
 | 4053 |         // Handle pointer-to-members. | 
 | 4054 |         if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Callee)) | 
 | 4055 |           T = BinOp->getRHS()->getType(); | 
 | 4056 |         else if (MemberExpr *Mem = dyn_cast<MemberExpr>(Callee)) | 
 | 4057 |           T = Mem->getMemberDecl()->getType(); | 
 | 4058 |       } | 
 | 4059 |        | 
 | 4060 |       if (const PointerType *Ptr = T->getAs<PointerType>()) | 
 | 4061 |         T = Ptr->getPointeeType(); | 
 | 4062 |       else if (const BlockPointerType *Ptr = T->getAs<BlockPointerType>()) | 
 | 4063 |         T = Ptr->getPointeeType(); | 
 | 4064 |       else if (const MemberPointerType *MemPtr = T->getAs<MemberPointerType>()) | 
 | 4065 |         T = MemPtr->getPointeeType(); | 
 | 4066 |        | 
 | 4067 |       const FunctionType *FTy = T->getAs<FunctionType>(); | 
 | 4068 |       assert(FTy && "call to value not of function type?"); | 
 | 4069 |       ReturnsRetained = FTy->getExtInfo().getProducesResult(); | 
 | 4070 |  | 
 | 4071 |     // ActOnStmtExpr arranges things so that StmtExprs of retainable | 
 | 4072 |     // type always produce a +1 object. | 
 | 4073 |     } else if (isa<StmtExpr>(E)) { | 
 | 4074 |       ReturnsRetained = true; | 
 | 4075 |  | 
 | 4076 |     // For message sends and property references, we try to find an | 
 | 4077 |     // actual method.  FIXME: we should infer retention by selector in | 
 | 4078 |     // cases where we don't have an actual method. | 
 | 4079 |     } else { | 
| John McCall | fc4b191 | 2011-08-03 07:02:44 +0000 | [diff] [blame] | 4080 |       ObjCMethodDecl *D = 0; | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4081 |       if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) { | 
 | 4082 |         D = Send->getMethodDecl(); | 
 | 4083 |       } else { | 
 | 4084 |         CastExpr *CE = cast<CastExpr>(E); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4085 |         assert(CE->getCastKind() == CK_GetObjCProperty); | 
 | 4086 |         const ObjCPropertyRefExpr *PRE = CE->getSubExpr()->getObjCProperty(); | 
 | 4087 |         D = (PRE->isImplicitProperty() ? PRE->getImplicitPropertyGetter() : 0); | 
 | 4088 |       } | 
 | 4089 |  | 
 | 4090 |       ReturnsRetained = (D && D->hasAttr<NSReturnsRetainedAttr>()); | 
| John McCall | fc4b191 | 2011-08-03 07:02:44 +0000 | [diff] [blame] | 4091 |  | 
 | 4092 |       // Don't do reclaims on performSelector calls; despite their | 
 | 4093 |       // return type, the invoked method doesn't necessarily actually | 
 | 4094 |       // return an object. | 
 | 4095 |       if (!ReturnsRetained && | 
 | 4096 |           D && D->getMethodFamily() == OMF_performSelector) | 
 | 4097 |         return Owned(E); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4098 |     } | 
 | 4099 |  | 
| John McCall | 7e5e5f4 | 2011-07-07 06:58:02 +0000 | [diff] [blame] | 4100 |     ExprNeedsCleanups = true; | 
 | 4101 |  | 
| John McCall | 33e56f3 | 2011-09-10 06:18:15 +0000 | [diff] [blame] | 4102 |     CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject | 
 | 4103 |                                    : CK_ARCReclaimReturnedObject); | 
| John McCall | 7e5e5f4 | 2011-07-07 06:58:02 +0000 | [diff] [blame] | 4104 |     return Owned(ImplicitCastExpr::Create(Context, E->getType(), ck, E, 0, | 
 | 4105 |                                           VK_RValue)); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4106 |   } | 
 | 4107 |  | 
 | 4108 |   if (!getLangOptions().CPlusPlus) | 
 | 4109 |     return Owned(E); | 
| Douglas Gregor | 5132655 | 2009-12-24 18:51:59 +0000 | [diff] [blame] | 4110 |  | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 4111 |   const RecordType *RT = E->getType()->getAs<RecordType>(); | 
| Anders Carlsson | def1199 | 2009-05-30 20:36:53 +0000 | [diff] [blame] | 4112 |   if (!RT) | 
 | 4113 |     return Owned(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4114 |  | 
| John McCall | 86ff308 | 2010-02-04 22:26:26 +0000 | [diff] [blame] | 4115 |   // That should be enough to guarantee that this type is complete. | 
 | 4116 |   // If it has a trivial destructor, we can avoid the extra copy. | 
| Jeffrey Yasskin | b7ee2e5 | 2011-01-27 19:17:54 +0000 | [diff] [blame] | 4117 |   CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); | 
| John McCall | 507384f | 2010-08-12 02:40:37 +0000 | [diff] [blame] | 4118 |   if (RD->isInvalidDecl() || RD->hasTrivialDestructor()) | 
| John McCall | 86ff308 | 2010-02-04 22:26:26 +0000 | [diff] [blame] | 4119 |     return Owned(E); | 
 | 4120 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4121 |   CXXDestructorDecl *Destructor = LookupDestructor(RD); | 
 | 4122 |  | 
 | 4123 |   CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor); | 
 | 4124 |   if (Destructor) { | 
| Fariborz Jahanian | a83f7ed | 2009-08-03 19:13:25 +0000 | [diff] [blame] | 4125 |     MarkDeclarationReferenced(E->getExprLoc(), Destructor); | 
| John McCall | c91cc66 | 2010-04-07 00:41:46 +0000 | [diff] [blame] | 4126 |     CheckDestructorAccess(E->getExprLoc(), Destructor, | 
 | 4127 |                           PDiag(diag::err_access_dtor_temp) | 
 | 4128 |                             << E->getType()); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4129 |  | 
 | 4130 |     ExprTemporaries.push_back(Temp); | 
 | 4131 |     ExprNeedsCleanups = true; | 
| John McCall | c91cc66 | 2010-04-07 00:41:46 +0000 | [diff] [blame] | 4132 |   } | 
| Anders Carlsson | def1199 | 2009-05-30 20:36:53 +0000 | [diff] [blame] | 4133 |   return Owned(CXXBindTemporaryExpr::Create(Context, Temp, E)); | 
 | 4134 | } | 
 | 4135 |  | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 4136 | Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) { | 
| Anders Carlsson | 99ba36d | 2009-06-05 15:38:08 +0000 | [diff] [blame] | 4137 |   assert(SubExpr && "sub expression can't be null!"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4138 |  | 
| Douglas Gregor | 1f5f3a4 | 2009-12-03 17:10:37 +0000 | [diff] [blame] | 4139 |   unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries; | 
 | 4140 |   assert(ExprTemporaries.size() >= FirstTemporary); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4141 |   assert(ExprNeedsCleanups || ExprTemporaries.size() == FirstTemporary); | 
 | 4142 |   if (!ExprNeedsCleanups) | 
| Anders Carlsson | 99ba36d | 2009-06-05 15:38:08 +0000 | [diff] [blame] | 4143 |     return SubExpr; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4144 |  | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 4145 |   Expr *E = ExprWithCleanups::Create(Context, SubExpr, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4146 |                                      ExprTemporaries.begin() + FirstTemporary, | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 4147 |                                      ExprTemporaries.size() - FirstTemporary); | 
| Douglas Gregor | 1f5f3a4 | 2009-12-03 17:10:37 +0000 | [diff] [blame] | 4148 |   ExprTemporaries.erase(ExprTemporaries.begin() + FirstTemporary, | 
 | 4149 |                         ExprTemporaries.end()); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4150 |   ExprNeedsCleanups = false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4151 |  | 
| Anders Carlsson | 99ba36d | 2009-06-05 15:38:08 +0000 | [diff] [blame] | 4152 |   return E; | 
 | 4153 | } | 
 | 4154 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4155 | ExprResult | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 4156 | Sema::MaybeCreateExprWithCleanups(ExprResult SubExpr) { | 
| Douglas Gregor | 90f9382 | 2009-12-22 22:17:25 +0000 | [diff] [blame] | 4157 |   if (SubExpr.isInvalid()) | 
 | 4158 |     return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4159 |  | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 4160 |   return Owned(MaybeCreateExprWithCleanups(SubExpr.take())); | 
| Douglas Gregor | 90f9382 | 2009-12-22 22:17:25 +0000 | [diff] [blame] | 4161 | } | 
 | 4162 |  | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 4163 | Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) { | 
| Argyrios Kyrtzidis | bf8cafa | 2010-11-02 02:33:08 +0000 | [diff] [blame] | 4164 |   assert(SubStmt && "sub statement can't be null!"); | 
 | 4165 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4166 |   if (!ExprNeedsCleanups) | 
| Argyrios Kyrtzidis | bf8cafa | 2010-11-02 02:33:08 +0000 | [diff] [blame] | 4167 |     return SubStmt; | 
 | 4168 |  | 
 | 4169 |   // FIXME: In order to attach the temporaries, wrap the statement into | 
 | 4170 |   // a StmtExpr; currently this is only used for asm statements. | 
 | 4171 |   // This is hacky, either create a new CXXStmtWithTemporaries statement or | 
 | 4172 |   // a new AsmStmtWithTemporaries. | 
 | 4173 |   CompoundStmt *CompStmt = new (Context) CompoundStmt(Context, &SubStmt, 1, | 
 | 4174 |                                                       SourceLocation(), | 
 | 4175 |                                                       SourceLocation()); | 
 | 4176 |   Expr *E = new (Context) StmtExpr(CompStmt, Context.VoidTy, SourceLocation(), | 
 | 4177 |                                    SourceLocation()); | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 4178 |   return MaybeCreateExprWithCleanups(E); | 
| Argyrios Kyrtzidis | bf8cafa | 2010-11-02 02:33:08 +0000 | [diff] [blame] | 4179 | } | 
 | 4180 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 4181 | ExprResult | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4182 | Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 4183 |                                    tok::TokenKind OpKind, ParsedType &ObjectType, | 
| Douglas Gregor | d4dca08 | 2010-02-24 18:44:31 +0000 | [diff] [blame] | 4184 |                                    bool &MayBePseudoDestructor) { | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4185 |   // Since this might be a postfix expression, get rid of ParenListExprs. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 4186 |   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base); | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4187 |   if (Result.isInvalid()) return ExprError(); | 
 | 4188 |   Base = Result.get(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4189 |  | 
| John McCall | 3c3b7f9 | 2011-10-25 17:37:35 +0000 | [diff] [blame] | 4190 |   Result = CheckPlaceholderExpr(Base); | 
 | 4191 |   if (Result.isInvalid()) return ExprError(); | 
 | 4192 |   Base = Result.take(); | 
 | 4193 |  | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4194 |   QualType BaseType = Base->getType(); | 
| Douglas Gregor | d4dca08 | 2010-02-24 18:44:31 +0000 | [diff] [blame] | 4195 |   MayBePseudoDestructor = false; | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4196 |   if (BaseType->isDependentType()) { | 
| Douglas Gregor | 43d8863 | 2009-11-04 22:49:18 +0000 | [diff] [blame] | 4197 |     // If we have a pointer to a dependent type and are using the -> operator, | 
 | 4198 |     // the object type is the type that the pointer points to. We might still | 
 | 4199 |     // have enough information about that type to do something useful. | 
 | 4200 |     if (OpKind == tok::arrow) | 
 | 4201 |       if (const PointerType *Ptr = BaseType->getAs<PointerType>()) | 
 | 4202 |         BaseType = Ptr->getPointeeType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4203 |  | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 4204 |     ObjectType = ParsedType::make(BaseType); | 
| Douglas Gregor | d4dca08 | 2010-02-24 18:44:31 +0000 | [diff] [blame] | 4205 |     MayBePseudoDestructor = true; | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4206 |     return Owned(Base); | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4207 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4208 |  | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4209 |   // C++ [over.match.oper]p8: | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4210 |   //   [...] When operator->returns, the operator-> is applied  to the value | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4211 |   //   returned, with the original second operand. | 
 | 4212 |   if (OpKind == tok::arrow) { | 
| John McCall | c4e8321 | 2009-09-30 01:01:30 +0000 | [diff] [blame] | 4213 |     // The set of types we've considered so far. | 
| John McCall | 432887f | 2009-09-30 01:30:54 +0000 | [diff] [blame] | 4214 |     llvm::SmallPtrSet<CanQualType,8> CTypes; | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 4215 |     SmallVector<SourceLocation, 8> Locations; | 
| John McCall | 432887f | 2009-09-30 01:30:54 +0000 | [diff] [blame] | 4216 |     CTypes.insert(Context.getCanonicalType(BaseType)); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4217 |  | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4218 |     while (BaseType->isRecordType()) { | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4219 |       Result = BuildOverloadedArrowExpr(S, Base, OpLoc); | 
 | 4220 |       if (Result.isInvalid()) | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4221 |         return ExprError(); | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4222 |       Base = Result.get(); | 
 | 4223 |       if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(Base)) | 
| Anders Carlsson | de699e5 | 2009-10-13 22:55:59 +0000 | [diff] [blame] | 4224 |         Locations.push_back(OpCall->getDirectCallee()->getLocation()); | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4225 |       BaseType = Base->getType(); | 
| John McCall | c4e8321 | 2009-09-30 01:01:30 +0000 | [diff] [blame] | 4226 |       CanQualType CBaseType = Context.getCanonicalType(BaseType); | 
| John McCall | 432887f | 2009-09-30 01:30:54 +0000 | [diff] [blame] | 4227 |       if (!CTypes.insert(CBaseType)) { | 
| Fariborz Jahanian | 4a4e345 | 2009-09-30 00:19:41 +0000 | [diff] [blame] | 4228 |         Diag(OpLoc, diag::err_operator_arrow_circular); | 
| Fariborz Jahanian | 7a8233a | 2009-09-30 17:46:20 +0000 | [diff] [blame] | 4229 |         for (unsigned i = 0; i < Locations.size(); i++) | 
 | 4230 |           Diag(Locations[i], diag::note_declared_at); | 
| Fariborz Jahanian | 4a4e345 | 2009-09-30 00:19:41 +0000 | [diff] [blame] | 4231 |         return ExprError(); | 
 | 4232 |       } | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4233 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4234 |  | 
| Douglas Gregor | 31658df | 2009-11-20 19:58:21 +0000 | [diff] [blame] | 4235 |     if (BaseType->isPointerType()) | 
 | 4236 |       BaseType = BaseType->getPointeeType(); | 
 | 4237 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4238 |  | 
 | 4239 |   // We could end up with various non-record types here, such as extended | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4240 |   // vector types or Objective-C interfaces. Just return early and let | 
 | 4241 |   // ActOnMemberReferenceExpr do the work. | 
| Douglas Gregor | c68afe2 | 2009-09-03 21:38:09 +0000 | [diff] [blame] | 4242 |   if (!BaseType->isRecordType()) { | 
 | 4243 |     // C++ [basic.lookup.classref]p2: | 
 | 4244 |     //   [...] If the type of the object expression is of pointer to scalar | 
 | 4245 |     //   type, the unqualified-id is looked up in the context of the complete | 
 | 4246 |     //   postfix-expression. | 
| Douglas Gregor | d4dca08 | 2010-02-24 18:44:31 +0000 | [diff] [blame] | 4247 |     // | 
 | 4248 |     // This also indicates that we should be parsing a | 
 | 4249 |     // pseudo-destructor-name. | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 4250 |     ObjectType = ParsedType(); | 
| Douglas Gregor | d4dca08 | 2010-02-24 18:44:31 +0000 | [diff] [blame] | 4251 |     MayBePseudoDestructor = true; | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4252 |     return Owned(Base); | 
| Douglas Gregor | c68afe2 | 2009-09-03 21:38:09 +0000 | [diff] [blame] | 4253 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4254 |  | 
| Douglas Gregor | 03c5705 | 2009-11-17 05:17:33 +0000 | [diff] [blame] | 4255 |   // The object type must be complete (or dependent). | 
 | 4256 |   if (!BaseType->isDependentType() && | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4257 |       RequireCompleteType(OpLoc, BaseType, | 
| Douglas Gregor | 03c5705 | 2009-11-17 05:17:33 +0000 | [diff] [blame] | 4258 |                           PDiag(diag::err_incomplete_member_access))) | 
 | 4259 |     return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4260 |  | 
| Douglas Gregor | c68afe2 | 2009-09-03 21:38:09 +0000 | [diff] [blame] | 4261 |   // C++ [basic.lookup.classref]p2: | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4262 |   //   If the id-expression in a class member access (5.2.5) is an | 
| Douglas Gregor | 03c5705 | 2009-11-17 05:17:33 +0000 | [diff] [blame] | 4263 |   //   unqualified-id, and the type of the object expression is of a class | 
| Douglas Gregor | c68afe2 | 2009-09-03 21:38:09 +0000 | [diff] [blame] | 4264 |   //   type C (or of pointer to a class type C), the unqualified-id is looked | 
 | 4265 |   //   up in the scope of class C. [...] | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 4266 |   ObjectType = ParsedType::make(BaseType); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4267 |   return move(Base); | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 4268 | } | 
 | 4269 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 4270 | ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc, | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4271 |                                                    Expr *MemExpr) { | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4272 |   SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(NameLoc); | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4273 |   Diag(MemExpr->getLocStart(), diag::err_dtor_expr_without_call) | 
 | 4274 |     << isa<CXXPseudoDestructorExpr>(MemExpr) | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 4275 |     << FixItHint::CreateInsertion(ExpectedLParenLoc, "()"); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4276 |  | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4277 |   return ActOnCallExpr(/*Scope*/ 0, | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4278 |                        MemExpr, | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4279 |                        /*LPLoc*/ ExpectedLParenLoc, | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 4280 |                        MultiExprArg(), | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4281 |                        /*RPLoc*/ ExpectedLParenLoc); | 
 | 4282 | } | 
| Douglas Gregor | d4dca08 | 2010-02-24 18:44:31 +0000 | [diff] [blame] | 4283 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 4284 | ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base, | 
| John McCall | 2d9f5fa | 2011-02-25 05:21:17 +0000 | [diff] [blame] | 4285 |                                            SourceLocation OpLoc, | 
 | 4286 |                                            tok::TokenKind OpKind, | 
 | 4287 |                                            const CXXScopeSpec &SS, | 
 | 4288 |                                            TypeSourceInfo *ScopeTypeInfo, | 
 | 4289 |                                            SourceLocation CCLoc, | 
 | 4290 |                                            SourceLocation TildeLoc, | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4291 |                                          PseudoDestructorTypeStorage Destructed, | 
| John McCall | 2d9f5fa | 2011-02-25 05:21:17 +0000 | [diff] [blame] | 4292 |                                            bool HasTrailingLParen) { | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4293 |   TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4294 |  | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4295 |   // C++ [expr.pseudo]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4296 |   //   The left-hand side of the dot operator shall be of scalar type. The | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4297 |   //   left-hand side of the arrow operator shall be of pointer to scalar type. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4298 |   //   This scalar type is the object type. | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4299 |   QualType ObjectType = Base->getType(); | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4300 |   if (OpKind == tok::arrow) { | 
 | 4301 |     if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) { | 
 | 4302 |       ObjectType = Ptr->getPointeeType(); | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4303 |     } else if (!Base->isTypeDependent()) { | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4304 |       // The user wrote "p->" when she probably meant "p."; fix it. | 
 | 4305 |       Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) | 
 | 4306 |         << ObjectType << true | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 4307 |         << FixItHint::CreateReplacement(OpLoc, "."); | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4308 |       if (isSFINAEContext()) | 
 | 4309 |         return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4310 |  | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4311 |       OpKind = tok::period; | 
 | 4312 |     } | 
 | 4313 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4314 |  | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4315 |   if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) { | 
 | 4316 |     Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar) | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4317 |       << ObjectType << Base->getSourceRange(); | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4318 |     return ExprError(); | 
 | 4319 |   } | 
 | 4320 |  | 
 | 4321 |   // C++ [expr.pseudo]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4322 |   //   [...] The cv-unqualified versions of the object type and of the type | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4323 |   //   designated by the pseudo-destructor-name shall be the same type. | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4324 |   if (DestructedTypeInfo) { | 
 | 4325 |     QualType DestructedType = DestructedTypeInfo->getType(); | 
 | 4326 |     SourceLocation DestructedTypeStart | 
| Abramo Bagnara | bd054db | 2010-05-20 10:00:11 +0000 | [diff] [blame] | 4327 |       = DestructedTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4328 |     if (!DestructedType->isDependentType() && !ObjectType->isDependentType()) { | 
 | 4329 |       if (!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) { | 
 | 4330 |         Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch) | 
 | 4331 |           << ObjectType << DestructedType << Base->getSourceRange() | 
 | 4332 |           << DestructedTypeInfo->getTypeLoc().getLocalSourceRange(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4333 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4334 |         // Recover by setting the destructed type to the object type. | 
 | 4335 |         DestructedType = ObjectType; | 
 | 4336 |         DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType, | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4337 |                                                            DestructedTypeStart); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4338 |         Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo); | 
 | 4339 |       } else if (DestructedType.getObjCLifetime() !=  | 
 | 4340 |                                                 ObjectType.getObjCLifetime()) { | 
 | 4341 |          | 
 | 4342 |         if (DestructedType.getObjCLifetime() == Qualifiers::OCL_None) { | 
 | 4343 |           // Okay: just pretend that the user provided the correctly-qualified | 
 | 4344 |           // type. | 
 | 4345 |         } else { | 
 | 4346 |           Diag(DestructedTypeStart, diag::err_arc_pseudo_dtor_inconstant_quals) | 
 | 4347 |             << ObjectType << DestructedType << Base->getSourceRange() | 
 | 4348 |             << DestructedTypeInfo->getTypeLoc().getLocalSourceRange(); | 
 | 4349 |         } | 
 | 4350 |          | 
 | 4351 |         // Recover by setting the destructed type to the object type. | 
 | 4352 |         DestructedType = ObjectType; | 
 | 4353 |         DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType, | 
 | 4354 |                                                            DestructedTypeStart); | 
 | 4355 |         Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo); | 
 | 4356 |       } | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4357 |     } | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4358 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4359 |  | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4360 |   // C++ [expr.pseudo]p2: | 
 | 4361 |   //   [...] Furthermore, the two type-names in a pseudo-destructor-name of the | 
 | 4362 |   //   form | 
 | 4363 |   // | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4364 |   //     ::[opt] nested-name-specifier[opt] type-name :: ~ type-name | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4365 |   // | 
 | 4366 |   //   shall designate the same scalar type. | 
 | 4367 |   if (ScopeTypeInfo) { | 
 | 4368 |     QualType ScopeType = ScopeTypeInfo->getType(); | 
 | 4369 |     if (!ScopeType->isDependentType() && !ObjectType->isDependentType() && | 
| John McCall | 81e317a | 2010-06-11 17:36:40 +0000 | [diff] [blame] | 4370 |         !Context.hasSameUnqualifiedType(ScopeType, ObjectType)) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4371 |  | 
| Abramo Bagnara | bd054db | 2010-05-20 10:00:11 +0000 | [diff] [blame] | 4372 |       Diag(ScopeTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(), | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4373 |            diag::err_pseudo_dtor_type_mismatch) | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4374 |         << ObjectType << ScopeType << Base->getSourceRange() | 
| Abramo Bagnara | bd054db | 2010-05-20 10:00:11 +0000 | [diff] [blame] | 4375 |         << ScopeTypeInfo->getTypeLoc().getLocalSourceRange(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4376 |  | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4377 |       ScopeType = QualType(); | 
 | 4378 |       ScopeTypeInfo = 0; | 
 | 4379 |     } | 
 | 4380 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4381 |  | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4382 |   Expr *Result | 
 | 4383 |     = new (Context) CXXPseudoDestructorExpr(Context, Base, | 
 | 4384 |                                             OpKind == tok::arrow, OpLoc, | 
| Douglas Gregor | f3db29f | 2011-02-25 18:19:59 +0000 | [diff] [blame] | 4385 |                                             SS.getWithLocInContext(Context), | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4386 |                                             ScopeTypeInfo, | 
 | 4387 |                                             CCLoc, | 
 | 4388 |                                             TildeLoc, | 
 | 4389 |                                             Destructed); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4390 |  | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4391 |   if (HasTrailingLParen) | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4392 |     return Owned(Result); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4393 |  | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4394 |   return DiagnoseDtorReference(Destructed.getLocation(), Result); | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4395 | } | 
 | 4396 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 4397 | ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, | 
| John McCall | 2d9f5fa | 2011-02-25 05:21:17 +0000 | [diff] [blame] | 4398 |                                            SourceLocation OpLoc, | 
 | 4399 |                                            tok::TokenKind OpKind, | 
 | 4400 |                                            CXXScopeSpec &SS, | 
 | 4401 |                                            UnqualifiedId &FirstTypeName, | 
 | 4402 |                                            SourceLocation CCLoc, | 
 | 4403 |                                            SourceLocation TildeLoc, | 
 | 4404 |                                            UnqualifiedId &SecondTypeName, | 
 | 4405 |                                            bool HasTrailingLParen) { | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4406 |   assert((FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId || | 
 | 4407 |           FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) && | 
 | 4408 |          "Invalid first type name in pseudo-destructor"); | 
 | 4409 |   assert((SecondTypeName.getKind() == UnqualifiedId::IK_TemplateId || | 
 | 4410 |           SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) && | 
 | 4411 |          "Invalid second type name in pseudo-destructor"); | 
 | 4412 |  | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4413 |   // C++ [expr.pseudo]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4414 |   //   The left-hand side of the dot operator shall be of scalar type. The | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4415 |   //   left-hand side of the arrow operator shall be of pointer to scalar type. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4416 |   //   This scalar type is the object type. | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4417 |   QualType ObjectType = Base->getType(); | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4418 |   if (OpKind == tok::arrow) { | 
 | 4419 |     if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) { | 
 | 4420 |       ObjectType = Ptr->getPointeeType(); | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4421 |     } else if (!ObjectType->isDependentType()) { | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4422 |       // The user wrote "p->" when she probably meant "p."; fix it. | 
 | 4423 |       Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4424 |         << ObjectType << true | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 4425 |         << FixItHint::CreateReplacement(OpLoc, "."); | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4426 |       if (isSFINAEContext()) | 
 | 4427 |         return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4428 |  | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4429 |       OpKind = tok::period; | 
 | 4430 |     } | 
 | 4431 |   } | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4432 |  | 
 | 4433 |   // Compute the object type that we should use for name lookup purposes. Only | 
 | 4434 |   // record types and dependent types matter. | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 4435 |   ParsedType ObjectTypePtrForLookup; | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4436 |   if (!SS.isSet()) { | 
| John McCall | 2d9f5fa | 2011-02-25 05:21:17 +0000 | [diff] [blame] | 4437 |     if (ObjectType->isRecordType()) | 
 | 4438 |       ObjectTypePtrForLookup = ParsedType::make(ObjectType); | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 4439 |     else if (ObjectType->isDependentType()) | 
 | 4440 |       ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy); | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4441 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4442 |  | 
 | 4443 |   // Convert the name of the type being destructed (following the ~) into a | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4444 |   // type (with source-location information). | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4445 |   QualType DestructedType; | 
 | 4446 |   TypeSourceInfo *DestructedTypeInfo = 0; | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4447 |   PseudoDestructorTypeStorage Destructed; | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4448 |   if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4449 |     ParsedType T = getTypeName(*SecondTypeName.Identifier, | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 4450 |                                SecondTypeName.StartLocation, | 
| Fariborz Jahanian | 1e52dfc | 2011-02-08 18:05:59 +0000 | [diff] [blame] | 4451 |                                S, &SS, true, false, ObjectTypePtrForLookup); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4452 |     if (!T && | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4453 |         ((SS.isSet() && !computeDeclContext(SS, false)) || | 
 | 4454 |          (!SS.isSet() && ObjectType->isDependentType()))) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4455 |       // The name of the type being destroyed is a dependent name, and we | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4456 |       // couldn't find anything useful in scope. Just store the identifier and | 
 | 4457 |       // it's location, and we'll perform (qualified) name lookup again at | 
 | 4458 |       // template instantiation time. | 
 | 4459 |       Destructed = PseudoDestructorTypeStorage(SecondTypeName.Identifier, | 
 | 4460 |                                                SecondTypeName.StartLocation); | 
 | 4461 |     } else if (!T) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4462 |       Diag(SecondTypeName.StartLocation, | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4463 |            diag::err_pseudo_dtor_destructor_non_type) | 
 | 4464 |         << SecondTypeName.Identifier << ObjectType; | 
 | 4465 |       if (isSFINAEContext()) | 
 | 4466 |         return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4467 |  | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4468 |       // Recover by assuming we had the right type all along. | 
 | 4469 |       DestructedType = ObjectType; | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4470 |     } else | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4471 |       DestructedType = GetTypeFromParser(T, &DestructedTypeInfo); | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4472 |   } else { | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4473 |     // Resolve the template-id to a type. | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4474 |     TemplateIdAnnotation *TemplateId = SecondTypeName.TemplateId; | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4475 |     ASTTemplateArgsPtr TemplateArgsPtr(*this, | 
 | 4476 |                                        TemplateId->getTemplateArgs(), | 
 | 4477 |                                        TemplateId->NumArgs); | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 4478 |     TypeResult T = ActOnTemplateIdType(TemplateId->SS, | 
 | 4479 |                                        TemplateId->Template, | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4480 |                                        TemplateId->TemplateNameLoc, | 
 | 4481 |                                        TemplateId->LAngleLoc, | 
 | 4482 |                                        TemplateArgsPtr, | 
 | 4483 |                                        TemplateId->RAngleLoc); | 
 | 4484 |     if (T.isInvalid() || !T.get()) { | 
 | 4485 |       // Recover by assuming we had the right type all along. | 
 | 4486 |       DestructedType = ObjectType; | 
 | 4487 |     } else | 
 | 4488 |       DestructedType = GetTypeFromParser(T.get(), &DestructedTypeInfo); | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4489 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4490 |  | 
 | 4491 |   // If we've performed some kind of recovery, (re-)build the type source | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4492 |   // information. | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4493 |   if (!DestructedType.isNull()) { | 
 | 4494 |     if (!DestructedTypeInfo) | 
 | 4495 |       DestructedTypeInfo = Context.getTrivialTypeSourceInfo(DestructedType, | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4496 |                                                   SecondTypeName.StartLocation); | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4497 |     Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo); | 
 | 4498 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4499 |  | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4500 |   // Convert the name of the scope type (the type prior to '::') into a type. | 
 | 4501 |   TypeSourceInfo *ScopeTypeInfo = 0; | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4502 |   QualType ScopeType; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4503 |   if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId || | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4504 |       FirstTypeName.Identifier) { | 
 | 4505 |     if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4506 |       ParsedType T = getTypeName(*FirstTypeName.Identifier, | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 4507 |                                  FirstTypeName.StartLocation, | 
| Douglas Gregor | f3db29f | 2011-02-25 18:19:59 +0000 | [diff] [blame] | 4508 |                                  S, &SS, true, false, ObjectTypePtrForLookup); | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4509 |       if (!T) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4510 |         Diag(FirstTypeName.StartLocation, | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4511 |              diag::err_pseudo_dtor_destructor_non_type) | 
 | 4512 |           << FirstTypeName.Identifier << ObjectType; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4513 |  | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4514 |         if (isSFINAEContext()) | 
 | 4515 |           return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4516 |  | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4517 |         // Just drop this type. It's unnecessary anyway. | 
 | 4518 |         ScopeType = QualType(); | 
 | 4519 |       } else | 
 | 4520 |         ScopeType = GetTypeFromParser(T, &ScopeTypeInfo); | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4521 |     } else { | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4522 |       // Resolve the template-id to a type. | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4523 |       TemplateIdAnnotation *TemplateId = FirstTypeName.TemplateId; | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4524 |       ASTTemplateArgsPtr TemplateArgsPtr(*this, | 
 | 4525 |                                          TemplateId->getTemplateArgs(), | 
 | 4526 |                                          TemplateId->NumArgs); | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 4527 |       TypeResult T = ActOnTemplateIdType(TemplateId->SS, | 
 | 4528 |                                          TemplateId->Template, | 
| Douglas Gregor | b57fb49 | 2010-02-24 22:38:50 +0000 | [diff] [blame] | 4529 |                                          TemplateId->TemplateNameLoc, | 
 | 4530 |                                          TemplateId->LAngleLoc, | 
 | 4531 |                                          TemplateArgsPtr, | 
 | 4532 |                                          TemplateId->RAngleLoc); | 
 | 4533 |       if (T.isInvalid() || !T.get()) { | 
 | 4534 |         // Recover by dropping this type. | 
 | 4535 |         ScopeType = QualType(); | 
 | 4536 |       } else | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4537 |         ScopeType = GetTypeFromParser(T.get(), &ScopeTypeInfo); | 
| Douglas Gregor | 7754908 | 2010-02-24 21:29:12 +0000 | [diff] [blame] | 4538 |     } | 
 | 4539 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4540 |  | 
| Douglas Gregor | b4a418f | 2010-02-24 23:02:30 +0000 | [diff] [blame] | 4541 |   if (!ScopeType.isNull() && !ScopeTypeInfo) | 
 | 4542 |     ScopeTypeInfo = Context.getTrivialTypeSourceInfo(ScopeType, | 
 | 4543 |                                                   FirstTypeName.StartLocation); | 
 | 4544 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4545 |  | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 4546 |   return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS, | 
| Douglas Gregor | fce46ee | 2010-02-24 23:50:37 +0000 | [diff] [blame] | 4547 |                                    ScopeTypeInfo, CCLoc, TildeLoc, | 
| Douglas Gregor | a2e7dd2 | 2010-02-25 01:56:36 +0000 | [diff] [blame] | 4548 |                                    Destructed, HasTrailingLParen); | 
| Douglas Gregor | d4dca08 | 2010-02-24 18:44:31 +0000 | [diff] [blame] | 4549 | } | 
 | 4550 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4551 | ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 4552 |                                         CXXMethodDecl *Method, | 
 | 4553 |                                         bool HadMultipleCandidates) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4554 |   ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/0, | 
 | 4555 |                                           FoundDecl, Method); | 
 | 4556 |   if (Exp.isInvalid()) | 
| Douglas Gregor | f2ae526 | 2011-01-20 00:18:04 +0000 | [diff] [blame] | 4557 |     return true; | 
| Eli Friedman | 772fffa | 2009-12-09 04:53:56 +0000 | [diff] [blame] | 4558 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4559 |   MemberExpr *ME = | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4560 |       new (Context) MemberExpr(Exp.take(), /*IsArrow=*/false, Method, | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 4561 |                                SourceLocation(), Method->getType(), | 
 | 4562 |                                VK_RValue, OK_Ordinary); | 
| Abramo Bagnara | 7cc58b4 | 2011-10-05 07:56:41 +0000 | [diff] [blame] | 4563 |   if (HadMultipleCandidates) | 
 | 4564 |     ME->setHadMultipleCandidates(true); | 
 | 4565 |  | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 4566 |   QualType ResultType = Method->getResultType(); | 
 | 4567 |   ExprValueKind VK = Expr::getValueKindForType(ResultType); | 
 | 4568 |   ResultType = ResultType.getNonLValueExprType(Context); | 
 | 4569 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4570 |   MarkDeclarationReferenced(Exp.get()->getLocStart(), Method); | 
| Douglas Gregor | 7edfb69 | 2009-11-23 12:27:39 +0000 | [diff] [blame] | 4571 |   CXXMemberCallExpr *CE = | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 4572 |     new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType, VK, | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4573 |                                     Exp.get()->getLocEnd()); | 
| Fariborz Jahanian | b740023 | 2009-09-28 23:23:40 +0000 | [diff] [blame] | 4574 |   return CE; | 
 | 4575 | } | 
 | 4576 |  | 
| Sebastian Redl | 2e15622 | 2010-09-10 20:55:43 +0000 | [diff] [blame] | 4577 | ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, | 
 | 4578 |                                       SourceLocation RParen) { | 
| Sebastian Redl | 2e15622 | 2010-09-10 20:55:43 +0000 | [diff] [blame] | 4579 |   return Owned(new (Context) CXXNoexceptExpr(Context.BoolTy, Operand, | 
 | 4580 |                                              Operand->CanThrow(Context), | 
 | 4581 |                                              KeyLoc, RParen)); | 
 | 4582 | } | 
 | 4583 |  | 
 | 4584 | ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation, | 
 | 4585 |                                    Expr *Operand, SourceLocation RParen) { | 
 | 4586 |   return BuildCXXNoexceptExpr(KeyLoc, Operand, RParen); | 
| Sebastian Redl | 02bc21a | 2010-09-10 20:55:37 +0000 | [diff] [blame] | 4587 | } | 
 | 4588 |  | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 4589 | /// Perform the conversions required for an expression used in a | 
 | 4590 | /// context that ignores the result. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4591 | ExprResult Sema::IgnoredValueConversions(Expr *E) { | 
| John McCall | 3c3b7f9 | 2011-10-25 17:37:35 +0000 | [diff] [blame] | 4592 |   if (E->hasPlaceholderType()) { | 
 | 4593 |     ExprResult result = CheckPlaceholderExpr(E); | 
 | 4594 |     if (result.isInvalid()) return Owned(E); | 
 | 4595 |     E = result.take(); | 
 | 4596 |   } | 
 | 4597 |  | 
| John McCall | a878cda | 2010-12-02 02:07:15 +0000 | [diff] [blame] | 4598 |   // C99 6.3.2.1: | 
 | 4599 |   //   [Except in specific positions,] an lvalue that does not have | 
 | 4600 |   //   array type is converted to the value stored in the | 
 | 4601 |   //   designated object (and is no longer an lvalue). | 
| John McCall | e6d134b | 2011-06-27 21:24:11 +0000 | [diff] [blame] | 4602 |   if (E->isRValue()) { | 
 | 4603 |     // In C, function designators (i.e. expressions of function type) | 
 | 4604 |     // are r-values, but we still want to do function-to-pointer decay | 
 | 4605 |     // on them.  This is both technically correct and convenient for | 
 | 4606 |     // some clients. | 
 | 4607 |     if (!getLangOptions().CPlusPlus && E->getType()->isFunctionType()) | 
 | 4608 |       return DefaultFunctionArrayConversion(E); | 
 | 4609 |  | 
 | 4610 |     return Owned(E); | 
 | 4611 |   } | 
| John McCall | a878cda | 2010-12-02 02:07:15 +0000 | [diff] [blame] | 4612 |  | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 4613 |   // Otherwise, this rule does not apply in C++, at least not for the moment. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4614 |   if (getLangOptions().CPlusPlus) return Owned(E); | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 4615 |  | 
 | 4616 |   // GCC seems to also exclude expressions of incomplete enum type. | 
 | 4617 |   if (const EnumType *T = E->getType()->getAs<EnumType>()) { | 
 | 4618 |     if (!T->getDecl()->isComplete()) { | 
 | 4619 |       // FIXME: stupid workaround for a codegen bug! | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4620 |       E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).take(); | 
 | 4621 |       return Owned(E); | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 4622 |     } | 
 | 4623 |   } | 
 | 4624 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4625 |   ExprResult Res = DefaultFunctionArrayLvalueConversion(E); | 
 | 4626 |   if (Res.isInvalid()) | 
 | 4627 |     return Owned(E); | 
 | 4628 |   E = Res.take(); | 
 | 4629 |  | 
| John McCall | 85515d6 | 2010-12-04 12:29:11 +0000 | [diff] [blame] | 4630 |   if (!E->getType()->isVoidType()) | 
 | 4631 |     RequireCompleteType(E->getExprLoc(), E->getType(), | 
 | 4632 |                         diag::err_incomplete_type); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4633 |   return Owned(E); | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 4634 | } | 
 | 4635 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4636 | ExprResult Sema::ActOnFinishFullExpr(Expr *FE) { | 
 | 4637 |   ExprResult FullExpr = Owned(FE); | 
 | 4638 |  | 
 | 4639 |   if (!FullExpr.get()) | 
| Douglas Gregor | bebbe0d | 2010-12-15 01:34:56 +0000 | [diff] [blame] | 4640 |     return ExprError(); | 
| John McCall | f6a1648 | 2010-12-04 03:47:34 +0000 | [diff] [blame] | 4641 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4642 |   if (DiagnoseUnexpandedParameterPack(FullExpr.get())) | 
| Douglas Gregor | d093722 | 2010-12-13 22:49:22 +0000 | [diff] [blame] | 4643 |     return ExprError(); | 
 | 4644 |  | 
| John McCall | fb8721c | 2011-04-10 19:13:55 +0000 | [diff] [blame] | 4645 |   FullExpr = CheckPlaceholderExpr(FullExpr.take()); | 
 | 4646 |   if (FullExpr.isInvalid()) | 
 | 4647 |     return ExprError(); | 
| Douglas Gregor | 353ee24 | 2011-03-07 02:05:23 +0000 | [diff] [blame] | 4648 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 4649 |   FullExpr = IgnoredValueConversions(FullExpr.take()); | 
 | 4650 |   if (FullExpr.isInvalid()) | 
 | 4651 |     return ExprError(); | 
 | 4652 |  | 
| Richard Trieu | f1f8b1a | 2011-09-23 20:10:00 +0000 | [diff] [blame] | 4653 |   CheckImplicitConversions(FullExpr.get(), FullExpr.get()->getExprLoc()); | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 4654 |   return MaybeCreateExprWithCleanups(FullExpr); | 
| Anders Carlsson | 165a0a0 | 2009-05-17 18:41:29 +0000 | [diff] [blame] | 4655 | } | 
| Argyrios Kyrtzidis | bf8cafa | 2010-11-02 02:33:08 +0000 | [diff] [blame] | 4656 |  | 
 | 4657 | StmtResult Sema::ActOnFinishFullStmt(Stmt *FullStmt) { | 
 | 4658 |   if (!FullStmt) return StmtError(); | 
 | 4659 |  | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 4660 |   return MaybeCreateStmtWithCleanups(FullStmt); | 
| Argyrios Kyrtzidis | bf8cafa | 2010-11-02 02:33:08 +0000 | [diff] [blame] | 4661 | } | 
| Francois Pichet | 1e86269 | 2011-05-06 20:48:22 +0000 | [diff] [blame] | 4662 |  | 
| Douglas Gregor | ba0513d | 2011-10-25 01:33:02 +0000 | [diff] [blame] | 4663 | Sema::IfExistsResult  | 
 | 4664 | Sema::CheckMicrosoftIfExistsSymbol(Scope *S, | 
 | 4665 |                                    CXXScopeSpec &SS, | 
 | 4666 |                                    const DeclarationNameInfo &TargetNameInfo) { | 
| Francois Pichet | 1e86269 | 2011-05-06 20:48:22 +0000 | [diff] [blame] | 4667 |   DeclarationName TargetName = TargetNameInfo.getName(); | 
 | 4668 |   if (!TargetName) | 
| Douglas Gregor | 3896fc5 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 4669 |     return IER_DoesNotExist; | 
| Douglas Gregor | ba0513d | 2011-10-25 01:33:02 +0000 | [diff] [blame] | 4670 |    | 
| Douglas Gregor | 3896fc5 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 4671 |   // If the name itself is dependent, then the result is dependent. | 
 | 4672 |   if (TargetName.isDependentName()) | 
 | 4673 |     return IER_Dependent; | 
| Douglas Gregor | ba0513d | 2011-10-25 01:33:02 +0000 | [diff] [blame] | 4674 |    | 
| Francois Pichet | 1e86269 | 2011-05-06 20:48:22 +0000 | [diff] [blame] | 4675 |   // Do the redeclaration lookup in the current scope. | 
 | 4676 |   LookupResult R(*this, TargetNameInfo, Sema::LookupAnyName, | 
 | 4677 |                  Sema::NotForRedeclaration); | 
| Douglas Gregor | 3896fc5 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 4678 |   LookupParsedName(R, S, &SS); | 
| Francois Pichet | 1e86269 | 2011-05-06 20:48:22 +0000 | [diff] [blame] | 4679 |   R.suppressDiagnostics(); | 
| Douglas Gregor | 3896fc5 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 4680 |    | 
 | 4681 |   switch (R.getResultKind()) { | 
 | 4682 |   case LookupResult::Found: | 
 | 4683 |   case LookupResult::FoundOverloaded: | 
 | 4684 |   case LookupResult::FoundUnresolvedValue: | 
 | 4685 |   case LookupResult::Ambiguous: | 
 | 4686 |     return IER_Exists; | 
 | 4687 |      | 
 | 4688 |   case LookupResult::NotFound: | 
 | 4689 |     return IER_DoesNotExist; | 
 | 4690 |      | 
 | 4691 |   case LookupResult::NotFoundInCurrentInstantiation: | 
 | 4692 |     return IER_Dependent; | 
 | 4693 |   } | 
 | 4694 |    | 
| Douglas Gregor | ba0513d | 2011-10-25 01:33:02 +0000 | [diff] [blame] | 4695 |   return IER_DoesNotExist;   | 
| Francois Pichet | 1e86269 | 2011-05-06 20:48:22 +0000 | [diff] [blame] | 4696 | } | 
| Douglas Gregor | ba0513d | 2011-10-25 01:33:02 +0000 | [diff] [blame] | 4697 |  | 
| Douglas Gregor | 65019ac | 2011-10-25 03:44:56 +0000 | [diff] [blame] | 4698 | Sema::IfExistsResult  | 
 | 4699 | Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc, | 
 | 4700 |                                    bool IsIfExists, CXXScopeSpec &SS, | 
 | 4701 |                                    UnqualifiedId &Name) { | 
| Douglas Gregor | ba0513d | 2011-10-25 01:33:02 +0000 | [diff] [blame] | 4702 |   DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name); | 
| Douglas Gregor | 65019ac | 2011-10-25 03:44:56 +0000 | [diff] [blame] | 4703 |    | 
 | 4704 |   // Check for unexpanded parameter packs. | 
 | 4705 |   SmallVector<UnexpandedParameterPack, 4> Unexpanded; | 
 | 4706 |   collectUnexpandedParameterPacks(SS, Unexpanded); | 
 | 4707 |   collectUnexpandedParameterPacks(TargetNameInfo, Unexpanded); | 
 | 4708 |   if (!Unexpanded.empty()) { | 
 | 4709 |     DiagnoseUnexpandedParameterPacks(KeywordLoc, | 
 | 4710 |                                      IsIfExists? UPPC_IfExists  | 
 | 4711 |                                                : UPPC_IfNotExists,  | 
 | 4712 |                                      Unexpanded); | 
 | 4713 |     return IER_Error; | 
 | 4714 |   } | 
 | 4715 |    | 
| Douglas Gregor | ba0513d | 2011-10-25 01:33:02 +0000 | [diff] [blame] | 4716 |   return CheckMicrosoftIfExistsSymbol(S, SS, TargetNameInfo); | 
 | 4717 | } | 
 | 4718 |  |