SemaExprCXX.cpp revision 4021a84eb1634a1e18bb3c258274477e8fdcd861
1//===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file implements semantic analysis for C++ expressions.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Sema.h"
15#include "clang/AST/ExprCXX.h"
16#include "clang/AST/ASTContext.h"
17#include "clang/Parse/DeclSpec.h"
18#include "clang/Lex/Preprocessor.h"
19#include "clang/Basic/Diagnostic.h"
20using namespace clang;
21
22/// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
23Action::ExprResult
24Sema::ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
25                    SourceLocation LAngleBracketLoc, TypeTy *Ty,
26                    SourceLocation RAngleBracketLoc,
27                    SourceLocation LParenLoc, ExprTy *E,
28                    SourceLocation RParenLoc) {
29  CXXCastExpr::Opcode Op;
30
31  switch (Kind) {
32  default: assert(0 && "Unknown C++ cast!");
33  case tok::kw_const_cast:       Op = CXXCastExpr::ConstCast;       break;
34  case tok::kw_dynamic_cast:     Op = CXXCastExpr::DynamicCast;     break;
35  case tok::kw_reinterpret_cast: Op = CXXCastExpr::ReinterpretCast; break;
36  case tok::kw_static_cast:      Op = CXXCastExpr::StaticCast;      break;
37  }
38
39  return new CXXCastExpr(Op, QualType::getFromOpaquePtr(Ty), (Expr*)E, OpLoc);
40}
41
42/// ActOnCXXBoolLiteral - Parse {true,false} literals.
43Action::ExprResult
44Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
45  assert((Kind != tok::kw_true || Kind != tok::kw_false) &&
46         "Unknown C++ Boolean value!");
47  return new CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
48}
49
50/// ActOnCXXThrow - Parse throw expressions.
51Action::ExprResult
52Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprTy *E) {
53  return new CXXThrowExpr((Expr*)E, Context.VoidTy, OpLoc);
54}
55
56Action::ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
57  /// C++ 9.3.2: In the body of a non-static member function, the keyword this
58  /// is a non-lvalue expression whose value is the address of the object for
59  /// which the function is called.
60
61  if (!isa<FunctionDecl>(CurContext)) {
62    Diag(ThisLoc, diag::err_invalid_this_use);
63    return ExprResult(true);
64  }
65
66  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext))
67    if (MD->isInstance())
68      return new PredefinedExpr(ThisLoc, MD->getThisType(Context),
69                                PredefinedExpr::CXXThis);
70
71  return Diag(ThisLoc, diag::err_invalid_this_use);
72}
73
74/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
75/// Can be interpreted either as function-style casting ("int(x)")
76/// or class type construction ("ClassType(x,y,z)")
77/// or creation of a value-initialized type ("int()").
78Action::ExprResult
79Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
80                                SourceLocation LParenLoc,
81                                ExprTy **ExprTys, unsigned NumExprs,
82                                SourceLocation *CommaLocs,
83                                SourceLocation RParenLoc) {
84  assert(TypeRep && "Missing type!");
85  QualType Ty = QualType::getFromOpaquePtr(TypeRep);
86  Expr **Exprs = (Expr**)ExprTys;
87  SourceLocation TyBeginLoc = TypeRange.getBegin();
88  SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc);
89
90  if (const RecordType *RT = Ty->getAsRecordType()) {
91    // C++ 5.2.3p1:
92    // If the simple-type-specifier specifies a class type, the class type shall
93    // be complete.
94    //
95    if (!RT->getDecl()->isDefinition())
96      return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use,
97                  Ty.getAsString(), FullRange);
98
99    unsigned DiagID = PP.getDiagnostics().getCustomDiagID(Diagnostic::Error,
100                                    "class constructors are not supported yet");
101    return Diag(TyBeginLoc, DiagID);
102  }
103
104  // C++ 5.2.3p1:
105  // If the expression list is a single expression, the type conversion
106  // expression is equivalent (in definedness, and if defined in meaning) to the
107  // corresponding cast expression.
108  //
109  if (NumExprs == 1) {
110    if (CheckCastTypes(TypeRange, Ty, Exprs[0]))
111      return true;
112    return new CXXFunctionalCastExpr(Ty, TyBeginLoc, Exprs[0], RParenLoc);
113  }
114
115  // C++ 5.2.3p1:
116  // If the expression list specifies more than a single value, the type shall
117  // be a class with a suitably declared constructor.
118  //
119  if (NumExprs > 1)
120    return Diag(CommaLocs[0], diag::err_builtin_func_cast_more_than_one_arg,
121                FullRange);
122
123  assert(NumExprs == 0 && "Expected 0 expressions");
124
125  // C++ 5.2.3p2:
126  // The expression T(), where T is a simple-type-specifier for a non-array
127  // complete object type or the (possibly cv-qualified) void type, creates an
128  // rvalue of the specified type, which is value-initialized.
129  //
130  if (Ty->isArrayType())
131    return Diag(TyBeginLoc, diag::err_value_init_for_array_type, FullRange);
132  if (Ty->isIncompleteType() && !Ty->isVoidType())
133    return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use,
134                Ty.getAsString(), FullRange);
135
136  return new CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc);
137}
138
139
140/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
141/// C++ if/switch/while/for statement.
142/// e.g: "if (int x = f()) {...}"
143Action::ExprResult
144Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc,
145                                       Declarator &D,
146                                       SourceLocation EqualLoc,
147                                       ExprTy *AssignExprVal) {
148  assert(AssignExprVal && "Null assignment expression");
149
150  // C++ 6.4p2:
151  // The declarator shall not specify a function or an array.
152  // The type-specifier-seq shall not contain typedef and shall not declare a
153  // new class or enumeration.
154
155  assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
156         "Parser allowed 'typedef' as storage class of condition decl.");
157
158  QualType Ty = GetTypeForDeclarator(D, S);
159
160  if (Ty->isFunctionType()) { // The declarator shall not specify a function...
161    // We exit without creating a CXXConditionDeclExpr because a FunctionDecl
162    // would be created and CXXConditionDeclExpr wants a VarDecl.
163    return Diag(StartLoc, diag::err_invalid_use_of_function_type,
164                SourceRange(StartLoc, EqualLoc));
165  } else if (Ty->isArrayType()) { // ...or an array.
166    Diag(StartLoc, diag::err_invalid_use_of_array_type,
167         SourceRange(StartLoc, EqualLoc));
168  } else if (const RecordType *RT = Ty->getAsRecordType()) {
169    RecordDecl *RD = RT->getDecl();
170    // The type-specifier-seq shall not declare a new class...
171    if (RD->isDefinition() && (RD->getIdentifier() == 0 || S->isDeclScope(RD)))
172      Diag(RD->getLocation(), diag::err_type_defined_in_condition);
173  } else if (const EnumType *ET = Ty->getAsEnumType()) {
174    EnumDecl *ED = ET->getDecl();
175    // ...or enumeration.
176    if (ED->isDefinition() && (ED->getIdentifier() == 0 || S->isDeclScope(ED)))
177      Diag(ED->getLocation(), diag::err_type_defined_in_condition);
178  }
179
180  DeclTy *Dcl = ActOnDeclarator(S, D, 0);
181  if (!Dcl)
182    return true;
183  AddInitializerToDecl(Dcl, AssignExprVal);
184
185  return new CXXConditionDeclExpr(StartLoc, EqualLoc,
186                                       cast<VarDecl>(static_cast<Decl *>(Dcl)));
187}
188
189/// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.
190bool Sema::CheckCXXBooleanCondition(Expr *&CondExpr) {
191  // C++ 6.4p4:
192  // The value of a condition that is an initialized declaration in a statement
193  // other than a switch statement is the value of the declared variable
194  // implicitly converted to type bool. If that conversion is ill-formed, the
195  // program is ill-formed.
196  // The value of a condition that is an expression is the value of the
197  // expression, implicitly converted to bool.
198  //
199  QualType Ty = CondExpr->getType(); // Save the type.
200  AssignConvertType
201    ConvTy = CheckSingleAssignmentConstraints(Context.BoolTy, CondExpr);
202  if (ConvTy == Incompatible)
203    return Diag(CondExpr->getLocStart(), diag::err_typecheck_bool_condition,
204                Ty.getAsString(), CondExpr->getSourceRange());
205  return false;
206}
207
208/// Helper function to determine whether this is the (deprecated) C++
209/// conversion from a string literal to a pointer to non-const char or
210/// non-const wchar_t (for narrow and wide string literals,
211/// respectively).
212bool
213Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
214  // Look inside the implicit cast, if it exists.
215  if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(From))
216    From = Cast->getSubExpr();
217
218  // A string literal (2.13.4) that is not a wide string literal can
219  // be converted to an rvalue of type "pointer to char"; a wide
220  // string literal can be converted to an rvalue of type "pointer
221  // to wchar_t" (C++ 4.2p2).
222  if (StringLiteral *StrLit = dyn_cast<StringLiteral>(From))
223    if (const PointerType *ToPtrType = ToType->getAsPointerType())
224      if (const BuiltinType *ToPointeeType
225          = ToPtrType->getPointeeType()->getAsBuiltinType()) {
226        // This conversion is considered only when there is an
227        // explicit appropriate pointer target type (C++ 4.2p2).
228        if (ToPtrType->getPointeeType().getCVRQualifiers() == 0 &&
229            ((StrLit->isWide() && ToPointeeType->isWideCharType()) ||
230             (!StrLit->isWide() &&
231              (ToPointeeType->getKind() == BuiltinType::Char_U ||
232               ToPointeeType->getKind() == BuiltinType::Char_S))))
233          return true;
234      }
235
236  return false;
237}
238