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