diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-01-18 18:53:16 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-01-18 18:53:16 +0000 |
commit | cd965b97cfac7b7a53a835810ec2bc2ac7a9dd1a (patch) | |
tree | b0877cb15978c0240797b11024005e522b665bd3 | |
parent | f512e82f56671b695a32d019103e62a302838b7e (diff) |
Convert a few expression actions to smart pointers.
These actions are extremely widely used (identifier expressions and literals); still no performance regression.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62468 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Driver/PrintParserCallbacks.cpp | 63 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 69 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 43 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 232 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 6 |
8 files changed, 228 insertions, 204 deletions
diff --git a/Driver/PrintParserCallbacks.cpp b/Driver/PrintParserCallbacks.cpp index efde399fba..18a4a24c80 100644 --- a/Driver/PrintParserCallbacks.cpp +++ b/Driver/PrintParserCallbacks.cpp @@ -438,49 +438,66 @@ namespace { //===--------------------------------------------------------------------===// // Expression Parsing Callbacks. //===--------------------------------------------------------------------===// - + // Primary Expressions. - + /// ActOnIdentifierExpr - Parse an identifier in expression context. /// 'HasTrailingLParen' indicates whether or not the identifier has a '(' /// token immediately after it. - virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, - IdentifierInfo &II, - bool HasTrailingLParen, - const CXXScopeSpec *SS) { + virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, + IdentifierInfo &II, + bool HasTrailingLParen, + const CXXScopeSpec *SS) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - - virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc, - tok::TokenKind Kind) { + + virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr( + Scope *S, SourceLocation OperatorLoc, + OverloadedOperatorKind Op, + bool HasTrailingLParen, const CXXScopeSpec &SS) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - virtual ExprResult ActOnCharacterConstant(const Token &) { + virtual OwningExprResult ActOnCXXConversionFunctionExpr( + Scope *S, SourceLocation OperatorLoc, + TypeTy *Type, bool HasTrailingLParen, + const CXXScopeSpec &SS) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - virtual ExprResult ActOnNumericConstant(const Token &) { + virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc, + tok::TokenKind Kind) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - + + virtual OwningExprResult ActOnCharacterConstant(const Token &) { + llvm::cout << __FUNCTION__ << "\n"; + return ExprEmpty(); + } + + virtual OwningExprResult ActOnNumericConstant(const Token &) { + llvm::cout << __FUNCTION__ << "\n"; + return ExprEmpty(); + } + /// ActOnStringLiteral - The specified tokens were lexed as pasted string /// fragments (e.g. "foo" "bar" L"baz"). - virtual ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks) { + virtual OwningExprResult ActOnStringLiteral(const Token *Toks, + unsigned NumToks) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - - virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, - ExprTy *Val) { + + virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, + ExprArg Val) { llvm::cout << __FUNCTION__ << "\n"; - return Val; // Default impl returns operand. + return move_res(Val); // Default impl returns operand. } - + // Postfix Expressions. virtual ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Kind, ExprTy *Input) { diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 51524eb75d..1b47f0a0d9 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -523,20 +523,20 @@ public: //===--------------------------------------------------------------------===// // Expression Parsing Callbacks. //===--------------------------------------------------------------------===// - + // Primary Expressions. - + /// ActOnIdentifierExpr - Parse an identifier in expression context. /// 'HasTrailingLParen' indicates whether or not the identifier has a '(' /// token immediately after it. /// An optional CXXScopeSpec can be passed to indicate the C++ scope (class or /// namespace) that the identifier must be a member of. /// i.e. for "foo::bar", 'II' will be "bar" and 'SS' will be "foo::". - virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, - IdentifierInfo &II, - bool HasTrailingLParen, - const CXXScopeSpec *SS = 0) { - return 0; + virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, + IdentifierInfo &II, + bool HasTrailingLParen, + const CXXScopeSpec *SS = 0) { + return ExprEmpty(); } /// ActOnOperatorFunctionIdExpr - Parse a C++ overloaded operator @@ -544,45 +544,48 @@ public: /// similar to ActOnIdentifierExpr, except that instead of providing /// an identifier the parser provides the kind of overloaded /// operator that was parsed. - virtual ExprResult ActOnCXXOperatorFunctionIdExpr(Scope *S, - SourceLocation OperatorLoc, - OverloadedOperatorKind Op, - bool HasTrailingLParen, - const CXXScopeSpec &SS) { - return 0; + virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr( + Scope *S, SourceLocation OperatorLoc, + OverloadedOperatorKind Op, + bool HasTrailingLParen, const CXXScopeSpec &SS) { + return ExprEmpty(); } - + /// ActOnCXXConversionFunctionExpr - Parse a C++ conversion function /// name (e.g., @c operator void const *) as an expression. This is /// very similar to ActOnIdentifierExpr, except that instead of /// providing an identifier the parser provides the type of the /// conversion function. - virtual ExprResult ActOnCXXConversionFunctionExpr(Scope *S, - SourceLocation OperatorLoc, - TypeTy *Type, - bool HasTrailingLParen, - const CXXScopeSpec &SS) { - return 0; + virtual OwningExprResult ActOnCXXConversionFunctionExpr( + Scope *S, SourceLocation OperatorLoc, + TypeTy *Type, bool HasTrailingLParen, + const CXXScopeSpec &SS) { + return ExprEmpty(); } - virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc, - tok::TokenKind Kind) { - return 0; + virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc, + tok::TokenKind Kind) { + return ExprEmpty(); } - virtual ExprResult ActOnCharacterConstant(const Token &) { return 0; } - virtual ExprResult ActOnNumericConstant(const Token &) { return 0; } - + virtual OwningExprResult ActOnCharacterConstant(const Token &) { + return ExprEmpty(); + } + virtual OwningExprResult ActOnNumericConstant(const Token &) { + return ExprEmpty(); + } + /// ActOnStringLiteral - The specified tokens were lexed as pasted string /// fragments (e.g. "foo" "bar" L"baz"). - virtual ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks) { - return 0; + virtual OwningExprResult ActOnStringLiteral(const Token *Toks, + unsigned NumToks) { + return ExprEmpty(); } - - virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, - ExprTy *Val) { - return Val; // Default impl returns operand. + + virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, + ExprArg Val) { + return move_res(Val); // Default impl returns operand. } - + // Postfix Expressions. virtual ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Kind, ExprTy *Input) { diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 319c03eecf..456acbeebd 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2105,7 +2105,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) { } else if (Tok.getKind() == tok::numeric_constant && GetLookAheadToken(1).is(tok::r_square)) { // [4] is very common. Parse the numeric constant expression. - OwningExprResult ExprRes(Actions, Actions.ActOnNumericConstant(Tok)); + OwningExprResult ExprRes(Actions.ActOnNumericConstant(Tok)); ConsumeToken(); MatchRHSPunctuation(tok::r_square, StartLoc); diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 0295f70633..c8c521d6aa 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1119,7 +1119,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, ExprType = SimpleExpr; if (!Result.isInvalid() && Tok.is(tok::r_paren)) Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), - Result.release()); + move_arg(Result)); } // Match the ')'. @@ -1155,7 +1155,7 @@ Parser::OwningExprResult Parser::ParseStringLiteralExpression() { } while (isTokenStringLiteral()); // Pass the set of string tokens, ready for concatenation, to the actions. - return Owned(Actions.ActOnStringLiteral(&StringToks[0], StringToks.size())); + return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size()); } /// ParseExpressionList - Used for C/C++ (argument-)expression-list. diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index d05c00292d..04e53a94ef 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -154,19 +154,18 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression() { // Consume the identifier so that we can see if it is followed by a '('. IdentifierInfo &II = *Tok.getIdentifierInfo(); SourceLocation L = ConsumeToken(); - return Owned(Actions.ActOnIdentifierExpr(CurScope, L, II, - Tok.is(tok::l_paren), &SS)); + return Actions.ActOnIdentifierExpr(CurScope, L, II, + Tok.is(tok::l_paren), &SS); } case tok::kw_operator: { SourceLocation OperatorLoc = Tok.getLocation(); if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) - return Owned(Actions.ActOnCXXOperatorFunctionIdExpr( - CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS)); + return Actions.ActOnCXXOperatorFunctionIdExpr( + CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS); if (TypeTy *Type = ParseConversionFunctionId()) - return Owned(Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, - Type, - Tok.is(tok::l_paren), SS)); + return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type, + Tok.is(tok::l_paren), SS); // We already complained about a bad conversion-function-id, // above. diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index eff8550bd1..b2c8aca966 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -943,16 +943,16 @@ public: // Expression Parsing Callbacks: SemaExpr.cpp. // Primary Expressions. - virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, - IdentifierInfo &II, - bool HasTrailingLParen, - const CXXScopeSpec *SS = 0); - virtual ExprResult ActOnCXXOperatorFunctionIdExpr(Scope *S, + virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, + IdentifierInfo &II, + bool HasTrailingLParen, + const CXXScopeSpec *SS = 0); + virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr(Scope *S, SourceLocation OperatorLoc, OverloadedOperatorKind Op, bool HasTrailingLParen, const CXXScopeSpec &SS); - virtual ExprResult ActOnCXXConversionFunctionExpr(Scope *S, + virtual OwningExprResult ActOnCXXConversionFunctionExpr(Scope *S, SourceLocation OperatorLoc, TypeTy *Ty, bool HasTrailingLParen, @@ -960,29 +960,28 @@ public: DeclRefExpr *BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc, bool TypeDependent, bool ValueDependent, const CXXScopeSpec *SS = 0); - ExprResult + OwningExprResult BuildAnonymousStructUnionMemberReference(SourceLocation Loc, FieldDecl *Field, Expr *BaseObjectExpr = 0, SourceLocation OpLoc = SourceLocation()); - ExprResult ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, - DeclarationName Name, - bool HasTrailingLParen, - const CXXScopeSpec *SS, - bool ForceResolution = false); - - - virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc, - tok::TokenKind Kind); - virtual ExprResult ActOnNumericConstant(const Token &); - virtual ExprResult ActOnCharacterConstant(const Token &); - virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, - ExprTy *Val); + OwningExprResult ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, + DeclarationName Name, + bool HasTrailingLParen, + const CXXScopeSpec *SS, + bool ForceResolution = false); + + virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc, + tok::TokenKind Kind); + virtual OwningExprResult ActOnNumericConstant(const Token &); + virtual OwningExprResult ActOnCharacterConstant(const Token &); + virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, + ExprArg Val); /// ActOnStringLiteral - The specified tokens were lexed as pasted string /// fragments (e.g. "foo" "bar" L"baz"). - virtual ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks); - + virtual OwningExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks); + // Binary/Unary Operators. 'Tok' is the token for the operator. virtual ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, ExprTy *Input); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2bc6ff2f12..880c840fd4 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -290,14 +290,14 @@ QualType Sema::UsualArithmeticConversionsType(QualType lhs, QualType rhs) { /// concatenation ([C99 5.1.1.2, translation phase #6]), so it may come from /// multiple tokens. However, the common case is that StringToks points to one /// string. -/// -Action::ExprResult +/// +Action::OwningExprResult Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) { assert(NumStringToks && "Must have at least one string!"); StringLiteralParser Literal(StringToks, NumStringToks, PP); if (Literal.hadError) - return ExprResult(true); + return ExprError(); llvm::SmallVector<SourceLocation, 4> StringTokLocs; for (unsigned i = 0; i != NumStringToks; ++i) @@ -310,19 +310,19 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) { // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). if (getLangOptions().CPlusPlus) StrTy.addConst(); - + // Get an array type for the string, according to C99 6.4.5. This includes // the nul terminator character as well as the string length for pascal // strings. StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Literal.GetStringLength()+1), ArrayType::Normal, 0); - + // Pass &StringTokLocs[0], StringTokLocs.size() to factory! - return new StringLiteral(Literal.GetString(), Literal.GetStringLength(), - Literal.AnyWide, StrTy, - StringToks[0].getLocation(), - StringToks[NumStringToks-1].getLocation()); + return Owned(new StringLiteral(Literal.GetString(), Literal.GetStringLength(), + Literal.AnyWide, StrTy, + StringToks[0].getLocation(), + StringToks[NumStringToks-1].getLocation())); } /// ShouldSnapshotBlockValueReference - Return true if a reference inside of @@ -358,12 +358,12 @@ static bool ShouldSnapshotBlockValueReference(BlockSemaInfo *CurBlock, /// ActOnIdentifierExpr - The parser read an identifier in expression context, /// validate it per-C99 6.5.1. HasTrailingLParen indicates whether this /// identifier is used in a function call context. -/// LookupCtx is only used for a C++ qualified-id (foo::bar) to indicate the +/// SS is only used for a C++ qualified-id (foo::bar) to indicate the /// class or namespace that the identifier must be a member of. -Sema::ExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc, - IdentifierInfo &II, - bool HasTrailingLParen, - const CXXScopeSpec *SS) { +Sema::OwningExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc, + IdentifierInfo &II, + bool HasTrailingLParen, + const CXXScopeSpec *SS) { return ActOnDeclarationNameExpr(S, Loc, &II, HasTrailingLParen, SS); } @@ -409,7 +409,7 @@ static ScopedDecl *getObjectForAnonymousRecordDecl(RecordDecl *Record) { return 0; } -Sema::ExprResult +Sema::OwningExprResult Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, FieldDecl *Field, Expr *BaseObjectExpr, @@ -484,15 +484,15 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, BaseObjectIsPointer = true; } } else { - return Diag(Loc, diag::err_invalid_member_use_in_static_method) - << Field->getDeclName(); + return ExprError(Diag(Loc,diag::err_invalid_member_use_in_static_method) + << Field->getDeclName()); } ExtraQuals = MD->getTypeQualifiers(); } if (!BaseObjectExpr) - return Diag(Loc, diag::err_invalid_non_static_member_use) - << Field->getDeclName(); + return ExprError(Diag(Loc, diag::err_invalid_non_static_member_use) + << Field->getDeclName()); } // Build the implicit member references to the field of the @@ -514,7 +514,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, OpLoc = SourceLocation(); } - return Result; + return Owned(Result); } /// ActOnDeclarationNameExpr - The parser has read some kind of name @@ -535,11 +535,10 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, /// If ForceResolution is true, then we will attempt to resolve the /// name even if it looks like a dependent name. This option is off by /// default. -Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, - DeclarationName Name, - bool HasTrailingLParen, - const CXXScopeSpec *SS, - bool ForceResolution) { +Sema::OwningExprResult +Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, + DeclarationName Name, bool HasTrailingLParen, + const CXXScopeSpec *SS, bool ForceResolution) { if (S->getTemplateParamParent() && Name.getAsIdentifierInfo() && HasTrailingLParen && !SS && !ForceResolution) { // We've seen something of the form @@ -550,8 +549,8 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // to represent this name. Then, if it turns out that none of the // arguments are type-dependent, we'll force the resolution of the // dependent name at that point. - return new CXXDependentNameExpr(Name.getAsIdentifierInfo(), - Context.DependentTy, Loc); + return Owned(new CXXDependentNameExpr(Name.getAsIdentifierInfo(), + Context.DependentTy, Loc)); } // Could be enum-constant, value decl, instance variable, etc. @@ -560,16 +559,17 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, if (SS && !SS->isEmpty()) { DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep()); if (DC == 0) - return true; + return ExprError(); Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC); } else Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S); - if (Lookup.isAmbiguous()) - return DiagnoseAmbiguousLookup(Lookup, Name, Loc, - SS && SS->isSet()? SS->getRange() - : SourceRange()); - else + if (Lookup.isAmbiguous()) { + DiagnoseAmbiguousLookup(Lookup, Name, Loc, + SS && SS->isSet() ? SS->getRange() + : SourceRange()); + return ExprError(); + } else D = Lookup.getAsDecl(); // If this reference is in an Objective-C method, then ivar lookup happens as @@ -588,18 +588,19 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // FIXME: This should use a new expr for a direct reference, don't turn // this into Self->ivar, just return a BareIVarExpr or something. IdentifierInfo &II = Context.Idents.get("self"); - ExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false); - ObjCIvarRefExpr *MRef= new ObjCIvarRefExpr(IV, IV->getType(), Loc, - static_cast<Expr*>(SelfExpr.Val), true, true); + OwningExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false); + ObjCIvarRefExpr *MRef = new ObjCIvarRefExpr(IV, IV->getType(), Loc, + static_cast<Expr*>(SelfExpr.release()), + true, true); Context.setFieldDecl(IFace, IV, MRef); - return MRef; + return Owned(MRef); } } // Needed to implement property "super.method" notation. if (SD == 0 && II->isStr("super")) { QualType T = Context.getPointerType(Context.getObjCInterfaceType( getCurMethodDecl()->getClassInterface())); - return new ObjCSuperExpr(Loc, T); + return Owned(new ObjCSuperExpr(Loc, T)); } } if (D == 0) { @@ -612,13 +613,14 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // If this name wasn't predeclared and if this is not a function call, // diagnose the problem. if (SS && !SS->isEmpty()) - return Diag(Loc, diag::err_typecheck_no_member) - << Name << SS->getRange(); + return ExprError(Diag(Loc, diag::err_typecheck_no_member) + << Name << SS->getRange()); else if (Name.getNameKind() == DeclarationName::CXXOperatorName || Name.getNameKind() == DeclarationName::CXXConversionFunctionName) - return Diag(Loc, diag::err_undeclared_use) << Name.getAsString(); + return ExprError(Diag(Loc, diag::err_undeclared_use) + << Name.getAsString()); else - return Diag(Loc, diag::err_undeclared_var_use) << Name; + return ExprError(Diag(Loc, diag::err_undeclared_var_use) << Name); } } @@ -627,7 +629,7 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion()) return BuildAnonymousStructUnionMemberReference(Loc, FD); - + if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) { if (!MD->isStatic()) { // C++ [class.mfct.nonstatic]p2: @@ -678,8 +680,8 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // Build the implicit member access expression. Expr *This = new CXXThisExpr(SourceLocation(), MD->getThisType(Context)); - return new MemberExpr(This, true, cast<NamedDecl>(D), - SourceLocation(), MemberType); + return Owned(new MemberExpr(This, true, cast<NamedDecl>(D), + SourceLocation(), MemberType)); } } } @@ -689,34 +691,35 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) { if (MD->isStatic()) // "invalid use of member 'x' in static member function" - return Diag(Loc, diag::err_invalid_member_use_in_static_method) - << FD->getDeclName(); + return ExprError(Diag(Loc,diag::err_invalid_member_use_in_static_method) + << FD->getDeclName()); } // Any other ways we could have found the field in a well-formed // program would have been turned into implicit member expressions // above. - return Diag(Loc, diag::err_invalid_non_static_member_use) - << FD->getDeclName(); + return ExprError(Diag(Loc, diag::err_invalid_non_static_member_use) + << FD->getDeclName()); } if (isa<TypedefDecl>(D)) - return Diag(Loc, diag::err_unexpected_typedef) << Name; + return ExprError(Diag(Loc, diag::err_unexpected_typedef) << Name); if (isa<ObjCInterfaceDecl>(D)) - return Diag(Loc, diag::err_unexpected_interface) << Name; + return ExprError(Diag(Loc, diag::err_unexpected_interface) << Name); if (isa<NamespaceDecl>(D)) - return Diag(Loc, diag::err_unexpected_namespace) << Name; + return ExprError(Diag(Loc, diag::err_unexpected_namespace) << Name); // Make the DeclRefExpr or BlockDeclRefExpr for the decl. if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D)) - return BuildDeclRefExpr(Ovl, Context.OverloadTy, Loc, false, false, SS); + return Owned(BuildDeclRefExpr(Ovl, Context.OverloadTy, Loc, + false, false, SS)); ValueDecl *VD = cast<ValueDecl>(D); - + // check if referencing an identifier with __attribute__((deprecated)). if (VD->getAttr<DeprecatedAttr>()) - Diag(Loc, diag::warn_deprecated) << VD->getDeclName(); - + ExprError(Diag(Loc, diag::warn_deprecated) << VD->getDeclName()); + if (VarDecl *Var = dyn_cast<VarDecl>(VD)) { if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) { Scope *CheckS = S; @@ -724,9 +727,11 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, if (CheckS->isWithinElse() && CheckS->getControlParent()->isDeclScope(Var)) { if (Var->getType()->isBooleanType()) - Diag(Loc, diag::warn_value_always_false) << Var->getDeclName(); + ExprError(Diag(Loc, diag::warn_value_always_false) + << Var->getDeclName()); else - Diag(Loc, diag::warn_value_always_zero) << Var->getDeclName(); + ExprError(Diag(Loc, diag::warn_value_always_zero) + << Var->getDeclName()); break; } @@ -740,8 +745,8 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // Only create DeclRefExpr's for valid Decl's. if (VD->isInvalidDecl()) - return true; - + return ExprError(); + // If the identifier reference is inside a block, and it refers to a value // that is outside the block, create a BlockDeclRefExpr instead of a // DeclRefExpr. This ensures the value is treated as a copy-in snapshot when @@ -753,13 +758,13 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, if (CurBlock && ShouldSnapshotBlockValueReference(CurBlock, VD)) { // The BlocksAttr indicates the variable is bound by-reference. if (VD->getAttr<BlocksAttr>()) - return new BlockDeclRefExpr(VD, VD->getType().getNonReferenceType(), - Loc, true); - + return Owned(new BlockDeclRefExpr(VD, VD->getType().getNonReferenceType(), + Loc, true)); + // Variable will be bound by-copy, make it const within the closure. VD->getType().addConst(); - return new BlockDeclRefExpr(VD, VD->getType().getNonReferenceType(), - Loc, false); + return Owned(new BlockDeclRefExpr(VD, VD->getType().getNonReferenceType(), + Loc, false)); } // If this reference is not in a block or if the referenced variable is // within the block, create a normal DeclRefExpr. @@ -807,14 +812,14 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // (FIXME!). } - return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, - TypeDependent, ValueDependent, SS); + return Owned(BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, + TypeDependent, ValueDependent, SS)); } -Sema::ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, - tok::TokenKind Kind) { +Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, + tok::TokenKind Kind) { PredefinedExpr::IdentType IT; - + switch (Kind) { default: assert(0 && "Unknown simple primary expr!"); case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2] @@ -834,57 +839,56 @@ Sema::ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, // __PRETTY_FUNCTION__ -> "top level", the others produce an empty string. Length = IT == PredefinedExpr::PrettyFunction ? strlen("top level") : 0; } - - + + llvm::APInt LengthI(32, Length + 1); QualType ResTy = Context.CharTy.getQualifiedType(QualType::Const); ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0); - return new PredefinedExpr(Loc, ResTy, IT); + return Owned(new PredefinedExpr(Loc, ResTy, IT)); } -Sema::ExprResult Sema::ActOnCharacterConstant(const Token &Tok) { +Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) { llvm::SmallString<16> CharBuffer; CharBuffer.resize(Tok.getLength()); const char *ThisTokBegin = &CharBuffer[0]; unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin); - + CharLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, Tok.getLocation(), PP); if (Literal.hadError()) - return ExprResult(true); + return ExprError(); QualType type = getLangOptions().CPlusPlus ? Context.CharTy : Context.IntTy; - return new CharacterLiteral(Literal.getValue(), Literal.isWide(), type, - Tok.getLocation()); + return Owned(new CharacterLiteral(Literal.getValue(), Literal.isWide(), type, + Tok.getLocation())); } -Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) { - // Fast path for a single digit (which is quite common). A single digit +Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) { + // Fast path for a single digit (which is quite common). A single digit // cannot have a trigraph, escaped newline, radix prefix, or type suffix. if (Tok.getLength() == 1) { const char Val = PP.getSpelledCharacterAt(Tok.getLocation()); unsigned IntSize = Context.Target.getIntWidth(); - return ExprResult(new IntegerLiteral(llvm::APInt(IntSize, Val-'0'), - Context.IntTy, - Tok.getLocation())); + return Owned(new IntegerLiteral(llvm::APInt(IntSize, Val-'0'), + Context.IntTy, Tok.getLocation())); } llvm::SmallString<512> IntegerBuffer; // Add padding so that NumericLiteralParser can overread by one character. IntegerBuffer.resize(Tok.getLength()+1); const char *ThisTokBegin = &IntegerBuffer[0]; - + // Get the spelling of the token, which eliminates trigraphs, etc. unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin); - + NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, Tok.getLocation(), PP); if (Literal.hadError) - return ExprResult(true); - + return ExprError(); + Expr *Res; - + if (Literal.isFloatingLiteral()) { QualType Ty; if (Literal.isFloat) @@ -900,9 +904,9 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) { bool isExact = false; Res = new FloatingLiteral(Literal.GetFloatValue(Format, &isExact), &isExact, Ty, Tok.getLocation()); - + } else if (!Literal.isIntegerLiteral()) { - return ExprResult(true); + return ExprError(); } else { QualType Ty; @@ -913,7 +917,7 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) { // Get the value in the widest-possible width. llvm::APInt ResultVal(Context.Target.getIntMaxTWidth(), 0); - + if (Literal.GetIntegerValue(ResultVal)) { // If this value didn't fit into uintmax_t, warn and force to ull. Diag(Tok.getLocation(), diag::warn_integer_too_large); @@ -923,7 +927,7 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) { } else { // If this value fits into a ULL, try to figure out what else it fits into // according to the rules of C99 6.4.4.1p5. - + // Octal, Hexadecimal, and integers with a U suffix are allowed to // be an unsigned int. bool AllowUnsigned = Literal.isUnsigned || Literal.getRadix() != 10; @@ -933,7 +937,7 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) { if (!Literal.isLong && !Literal.isLongLong) { // Are int/unsigned possibilities? unsigned IntSize = Context.Target.getIntWidth(); - + // Does it fit in a unsigned int? if (ResultVal.isIntN(IntSize)) { // Does it fit in a signed int? @@ -944,11 +948,11 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) { Width = IntSize; } } - + // Are long/unsigned long possibilities? if (Ty.isNull() && !Literal.isLongLong) { unsigned LongSize = Context.Target.getLongWidth(); - + |