SemaExprCXX.cpp revision 5921093cf1c2e9a8bd1a22b6f612e551bae7476b
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/Basic/Diagnostic.h"
19using namespace clang;
20
21/// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
22Action::ExprResult
23Sema::ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
24                    SourceLocation LAngleBracketLoc, TypeTy *Ty,
25                    SourceLocation RAngleBracketLoc,
26                    SourceLocation LParenLoc, ExprTy *E,
27                    SourceLocation RParenLoc) {
28  CXXCastExpr::Opcode Op;
29
30  switch (Kind) {
31  default: assert(0 && "Unknown C++ cast!");
32  case tok::kw_const_cast:       Op = CXXCastExpr::ConstCast;       break;
33  case tok::kw_dynamic_cast:     Op = CXXCastExpr::DynamicCast;     break;
34  case tok::kw_reinterpret_cast: Op = CXXCastExpr::ReinterpretCast; break;
35  case tok::kw_static_cast:      Op = CXXCastExpr::StaticCast;      break;
36  }
37
38  return new CXXCastExpr(Op, QualType::getFromOpaquePtr(Ty), (Expr*)E, OpLoc);
39}
40
41/// ActOnCXXBoolLiteral - Parse {true,false} literals.
42Action::ExprResult
43Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
44  assert((Kind != tok::kw_true || Kind != tok::kw_false) &&
45         "Unknown C++ Boolean value!");
46  return new CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
47}
48
49/// ActOnCXXThrow - Parse throw expressions.
50Action::ExprResult
51Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprTy *E) {
52  return new CXXThrowExpr((Expr*)E, Context.VoidTy, OpLoc);
53}
54
55Action::ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
56  /// C++ 9.3.2: In the body of a non-static member function, the keyword this
57  /// is a non-lvalue expression whose value is the address of the object for
58  /// which the function is called.
59
60  if (!isa<FunctionDecl>(CurContext)) {
61    Diag(ThisLoc, diag::err_invalid_this_use);
62    return ExprResult(true);
63  }
64
65  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext))
66    if (MD->isInstance())
67      return new PredefinedExpr(ThisLoc, MD->getThisType(Context),
68                                PredefinedExpr::CXXThis);
69
70  return Diag(ThisLoc, diag::err_invalid_this_use);
71}
72
73/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
74/// Can be interpreted either as function-style casting ("int(x)")
75/// or class type construction ("ClassType(x,y,z)")
76/// or creation of a value-initialized type ("int()").
77Action::ExprResult
78Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
79                                SourceLocation LParenLoc,
80                                ExprTy **ExprTys, unsigned NumExprs,
81                                SourceLocation *CommaLocs,
82                                SourceLocation RParenLoc) {
83  assert(TypeRep && "Missing type!");
84  QualType Ty = QualType::getFromOpaquePtr(TypeRep);
85  Expr **Exprs = (Expr**)ExprTys;
86  SourceLocation TyBeginLoc = TypeRange.getBegin();
87  SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc);
88
89  if (const RecordType *RT = Ty->getAsRecordType()) {
90    // C++ 5.2.3p1:
91    // If the simple-type-specifier specifies a class type, the class type shall
92    // be complete.
93    //
94    if (!RT->getDecl()->isDefinition())
95      return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use,
96                  Ty.getAsString(), FullRange);
97
98    // "class constructors are not supported yet"
99    return Diag(TyBeginLoc, diag::err_unsupported_class_constructor, FullRange);
100  }
101
102  // C++ 5.2.3p1:
103  // If the expression list is a single expression, the type conversion
104  // expression is equivalent (in definedness, and if defined in meaning) to the
105  // corresponding cast expression.
106  //
107  if (NumExprs == 1) {
108    if (CheckCastTypes(TypeRange, Ty, Exprs[0]))
109      return true;
110    return new CXXFunctionalCastExpr(Ty, TyBeginLoc, Exprs[0], RParenLoc);
111  }
112
113  // C++ 5.2.3p1:
114  // If the expression list specifies more than a single value, the type shall
115  // be a class with a suitably declared constructor.
116  //
117  if (NumExprs > 1)
118    return Diag(CommaLocs[0], diag::err_builtin_func_cast_more_than_one_arg,
119                FullRange);
120
121  assert(NumExprs == 0 && "Expected 0 expressions");
122
123  // C++ 5.2.3p2:
124  // The expression T(), where T is a simple-type-specifier for a non-array
125  // complete object type or the (possibly cv-qualified) void type, creates an
126  // rvalue of the specified type, which is value-initialized.
127  //
128  if (Ty->isArrayType())
129    return Diag(TyBeginLoc, diag::err_value_init_for_array_type, FullRange);
130  if (Ty->isIncompleteType() && !Ty->isVoidType())
131    return Diag(TyBeginLoc, diag::err_invalid_incomplete_type_use,
132                Ty.getAsString(), FullRange);
133
134  return new CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc);
135}
136
137
138/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
139/// C++ if/switch/while/for statement.
140/// e.g: "if (int x = f()) {...}"
141Action::ExprResult
142Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc,
143                                       Declarator &D,
144                                       SourceLocation EqualLoc,
145                                       ExprTy *AssignExprVal) {
146  assert(AssignExprVal && "Null assignment expression");
147
148  // C++ 6.4p2:
149  // The declarator shall not specify a function or an array.
150  // The type-specifier-seq shall not contain typedef and shall not declare a
151  // new class or enumeration.
152
153  assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
154         "Parser allowed 'typedef' as storage class of condition decl.");
155
156  QualType Ty = GetTypeForDeclarator(D, S);
157
158  if (Ty->isFunctionType()) { // The declarator shall not specify a function...
159    // We exit without creating a CXXConditionDeclExpr because a FunctionDecl
160    // would be created and CXXConditionDeclExpr wants a VarDecl.
161    return Diag(StartLoc, diag::err_invalid_use_of_function_type,
162                SourceRange(StartLoc, EqualLoc));
163  } else if (Ty->isArrayType()) { // ...or an array.
164    Diag(StartLoc, diag::err_invalid_use_of_array_type,
165         SourceRange(StartLoc, EqualLoc));
166  } else if (const RecordType *RT = Ty->getAsRecordType()) {
167    RecordDecl *RD = RT->getDecl();
168    // The type-specifier-seq shall not declare a new class...
169    if (RD->isDefinition() && (RD->getIdentifier() == 0 || S->isDeclScope(RD)))
170      Diag(RD->getLocation(), diag::err_type_defined_in_condition);
171  } else if (const EnumType *ET = Ty->getAsEnumType()) {
172    EnumDecl *ED = ET->getDecl();
173    // ...or enumeration.
174    if (ED->isDefinition() && (ED->getIdentifier() == 0 || S->isDeclScope(ED)))
175      Diag(ED->getLocation(), diag::err_type_defined_in_condition);
176  }
177
178  DeclTy *Dcl = ActOnDeclarator(S, D, 0);
179  if (!Dcl)
180    return true;
181  AddInitializerToDecl(Dcl, AssignExprVal);
182
183  return new CXXConditionDeclExpr(StartLoc, EqualLoc,
184                                       cast<VarDecl>(static_cast<Decl *>(Dcl)));
185}
186
187/// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.
188bool Sema::CheckCXXBooleanCondition(Expr *&CondExpr) {
189  // C++ 6.4p4:
190  // The value of a condition that is an initialized declaration in a statement
191  // other than a switch statement is the value of the declared variable
192  // implicitly converted to type bool. If that conversion is ill-formed, the
193  // program is ill-formed.
194  // The value of a condition that is an expression is the value of the
195  // expression, implicitly converted to bool.
196  //
197  QualType Ty = CondExpr->getType(); // Save the type.
198  AssignConvertType
199    ConvTy = CheckSingleAssignmentConstraints(Context.BoolTy, CondExpr);
200  if (ConvTy == Incompatible)
201    return Diag(CondExpr->getLocStart(), diag::err_typecheck_bool_condition,
202                Ty.getAsString(), CondExpr->getSourceRange());
203  return false;
204}
205