aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-01-18 18:53:16 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-01-18 18:53:16 +0000
commitcd965b97cfac7b7a53a835810ec2bc2ac7a9dd1a (patch)
treeb0877cb15978c0240797b11024005e522b665bd3
parentf512e82f56671b695a32d019103e62a302838b7e (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.cpp63
-rw-r--r--include/clang/Parse/Action.h69
-rw-r--r--lib/Parse/ParseDecl.cpp2
-rw-r--r--lib/Parse/ParseExpr.cpp4
-rw-r--r--lib/Parse/ParseExprCXX.cpp13
-rw-r--r--lib/Sema/Sema.h43
-rw-r--r--lib/Sema/SemaExpr.cpp232
-rw-r--r--lib/Sema/SemaExprCXX.cpp6
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();
-
+