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
This commit is contained in:
Sebastian Redl 2009-01-18 18:53:16 +00:00
Родитель f512e82f56
Коммит cd965b97cf
8 изменённых файлов: 229 добавлений и 205 удалений

Просмотреть файл

@ -438,49 +438,66 @@ namespace {
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Expression Parsing Callbacks. // Expression Parsing Callbacks.
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Primary Expressions. // Primary Expressions.
/// ActOnIdentifierExpr - Parse an identifier in expression context. /// ActOnIdentifierExpr - Parse an identifier in expression context.
/// 'HasTrailingLParen' indicates whether or not the identifier has a '(' /// 'HasTrailingLParen' indicates whether or not the identifier has a '('
/// token immediately after it. /// token immediately after it.
virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
IdentifierInfo &II, IdentifierInfo &II,
bool HasTrailingLParen, bool HasTrailingLParen,
const CXXScopeSpec *SS) { const CXXScopeSpec *SS) {
llvm::cout << __FUNCTION__ << "\n"; llvm::cout << __FUNCTION__ << "\n";
return 0; return ExprEmpty();
}
virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind) {
llvm::cout << __FUNCTION__ << "\n";
return 0;
} }
virtual ExprResult ActOnCharacterConstant(const Token &) { virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr(
Scope *S, SourceLocation OperatorLoc,
OverloadedOperatorKind Op,
bool HasTrailingLParen, const CXXScopeSpec &SS) {
llvm::cout << __FUNCTION__ << "\n"; llvm::cout << __FUNCTION__ << "\n";
return 0; return ExprEmpty();
} }
virtual ExprResult ActOnNumericConstant(const Token &) { virtual OwningExprResult ActOnCXXConversionFunctionExpr(
Scope *S, SourceLocation OperatorLoc,
TypeTy *Type, bool HasTrailingLParen,
const CXXScopeSpec &SS) {
llvm::cout << __FUNCTION__ << "\n"; llvm::cout << __FUNCTION__ << "\n";
return 0; return ExprEmpty();
} }
virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind) {
llvm::cout << __FUNCTION__ << "\n";
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 /// ActOnStringLiteral - The specified tokens were lexed as pasted string
/// fragments (e.g. "foo" "bar" L"baz"). /// 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"; llvm::cout << __FUNCTION__ << "\n";
return 0; return ExprEmpty();
} }
virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
ExprTy *Val) { ExprArg Val) {
llvm::cout << __FUNCTION__ << "\n"; llvm::cout << __FUNCTION__ << "\n";
return Val; // Default impl returns operand. return move_res(Val); // Default impl returns operand.
} }
// Postfix Expressions. // Postfix Expressions.
virtual ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, virtual ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
tok::TokenKind Kind, ExprTy *Input) { tok::TokenKind Kind, ExprTy *Input) {

Просмотреть файл

@ -523,20 +523,20 @@ public:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Expression Parsing Callbacks. // Expression Parsing Callbacks.
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Primary Expressions. // Primary Expressions.
/// ActOnIdentifierExpr - Parse an identifier in expression context. /// ActOnIdentifierExpr - Parse an identifier in expression context.
/// 'HasTrailingLParen' indicates whether or not the identifier has a '(' /// 'HasTrailingLParen' indicates whether or not the identifier has a '('
/// token immediately after it. /// token immediately after it.
/// An optional CXXScopeSpec can be passed to indicate the C++ scope (class or /// An optional CXXScopeSpec can be passed to indicate the C++ scope (class or
/// namespace) that the identifier must be a member of. /// namespace) that the identifier must be a member of.
/// i.e. for "foo::bar", 'II' will be "bar" and 'SS' will be "foo::". /// i.e. for "foo::bar", 'II' will be "bar" and 'SS' will be "foo::".
virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
IdentifierInfo &II, IdentifierInfo &II,
bool HasTrailingLParen, bool HasTrailingLParen,
const CXXScopeSpec *SS = 0) { const CXXScopeSpec *SS = 0) {
return 0; return ExprEmpty();
} }
/// ActOnOperatorFunctionIdExpr - Parse a C++ overloaded operator /// ActOnOperatorFunctionIdExpr - Parse a C++ overloaded operator
@ -544,45 +544,48 @@ public:
/// similar to ActOnIdentifierExpr, except that instead of providing /// similar to ActOnIdentifierExpr, except that instead of providing
/// an identifier the parser provides the kind of overloaded /// an identifier the parser provides the kind of overloaded
/// operator that was parsed. /// operator that was parsed.
virtual ExprResult ActOnCXXOperatorFunctionIdExpr(Scope *S, virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr(
SourceLocation OperatorLoc, Scope *S, SourceLocation OperatorLoc,
OverloadedOperatorKind Op, OverloadedOperatorKind Op,
bool HasTrailingLParen, bool HasTrailingLParen, const CXXScopeSpec &SS) {
const CXXScopeSpec &SS) { return ExprEmpty();
return 0;
} }
/// ActOnCXXConversionFunctionExpr - Parse a C++ conversion function /// ActOnCXXConversionFunctionExpr - Parse a C++ conversion function
/// name (e.g., @c operator void const *) as an expression. This is /// name (e.g., @c operator void const *) as an expression. This is
/// very similar to ActOnIdentifierExpr, except that instead of /// very similar to ActOnIdentifierExpr, except that instead of
/// providing an identifier the parser provides the type of the /// providing an identifier the parser provides the type of the
/// conversion function. /// conversion function.
virtual ExprResult ActOnCXXConversionFunctionExpr(Scope *S, virtual OwningExprResult ActOnCXXConversionFunctionExpr(
SourceLocation OperatorLoc, Scope *S, SourceLocation OperatorLoc,
TypeTy *Type, TypeTy *Type, bool HasTrailingLParen,
bool HasTrailingLParen, const CXXScopeSpec &SS) {
const CXXScopeSpec &SS) { return ExprEmpty();
return 0;
} }
virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc, virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind) { tok::TokenKind Kind) {
return 0; return ExprEmpty();
} }
virtual ExprResult ActOnCharacterConstant(const Token &) { return 0; } virtual OwningExprResult ActOnCharacterConstant(const Token &) {
virtual ExprResult ActOnNumericConstant(const Token &) { return 0; } return ExprEmpty();
}
virtual OwningExprResult ActOnNumericConstant(const Token &) {
return ExprEmpty();
}
/// ActOnStringLiteral - The specified tokens were lexed as pasted string /// ActOnStringLiteral - The specified tokens were lexed as pasted string
/// fragments (e.g. "foo" "bar" L"baz"). /// fragments (e.g. "foo" "bar" L"baz").
virtual ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks) { virtual OwningExprResult ActOnStringLiteral(const Token *Toks,
return 0; unsigned NumToks) {
return ExprEmpty();
} }
virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
ExprTy *Val) { ExprArg Val) {
return Val; // Default impl returns operand. return move_res(Val); // Default impl returns operand.
} }
// Postfix Expressions. // Postfix Expressions.
virtual ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, virtual ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
tok::TokenKind Kind, ExprTy *Input) { tok::TokenKind Kind, ExprTy *Input) {

Просмотреть файл

@ -2105,7 +2105,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
} else if (Tok.getKind() == tok::numeric_constant && } else if (Tok.getKind() == tok::numeric_constant &&
GetLookAheadToken(1).is(tok::r_square)) { GetLookAheadToken(1).is(tok::r_square)) {
// [4] is very common. Parse the numeric constant expression. // [4] is very common. Parse the numeric constant expression.
OwningExprResult ExprRes(Actions, Actions.ActOnNumericConstant(Tok)); OwningExprResult ExprRes(Actions.ActOnNumericConstant(Tok));
ConsumeToken(); ConsumeToken();
MatchRHSPunctuation(tok::r_square, StartLoc); MatchRHSPunctuation(tok::r_square, StartLoc);

Просмотреть файл

@ -1119,7 +1119,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType,
ExprType = SimpleExpr; ExprType = SimpleExpr;
if (!Result.isInvalid() && Tok.is(tok::r_paren)) if (!Result.isInvalid() && Tok.is(tok::r_paren))
Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(),
Result.release()); move_arg(Result));
} }
// Match the ')'. // Match the ')'.
@ -1155,7 +1155,7 @@ Parser::OwningExprResult Parser::ParseStringLiteralExpression() {
} while (isTokenStringLiteral()); } while (isTokenStringLiteral());
// Pass the set of string tokens, ready for concatenation, to the actions. // 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. /// ParseExpressionList - Used for C/C++ (argument-)expression-list.

Просмотреть файл

@ -154,19 +154,18 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression() {
// Consume the identifier so that we can see if it is followed by a '('. // Consume the identifier so that we can see if it is followed by a '('.
IdentifierInfo &II = *Tok.getIdentifierInfo(); IdentifierInfo &II = *Tok.getIdentifierInfo();
SourceLocation L = ConsumeToken(); SourceLocation L = ConsumeToken();
return Owned(Actions.ActOnIdentifierExpr(CurScope, L, II, return Actions.ActOnIdentifierExpr(CurScope, L, II,
Tok.is(tok::l_paren), &SS)); Tok.is(tok::l_paren), &SS);
} }
case tok::kw_operator: { case tok::kw_operator: {
SourceLocation OperatorLoc = Tok.getLocation(); SourceLocation OperatorLoc = Tok.getLocation();
if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) if (OverloadedOperatorKind Op = TryParseOperatorFunctionId())
return Owned(Actions.ActOnCXXOperatorFunctionIdExpr( return Actions.ActOnCXXOperatorFunctionIdExpr(
CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS)); CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS);
if (TypeTy *Type = ParseConversionFunctionId()) if (TypeTy *Type = ParseConversionFunctionId())
return Owned(Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type,
Type, Tok.is(tok::l_paren), SS);
Tok.is(tok::l_paren), SS));
// We already complained about a bad conversion-function-id, // We already complained about a bad conversion-function-id,
// above. // above.

Просмотреть файл

@ -943,16 +943,16 @@ public:
// Expression Parsing Callbacks: SemaExpr.cpp. // Expression Parsing Callbacks: SemaExpr.cpp.
// Primary Expressions. // Primary Expressions.
virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
IdentifierInfo &II, IdentifierInfo &II,
bool HasTrailingLParen, bool HasTrailingLParen,
const CXXScopeSpec *SS = 0); const CXXScopeSpec *SS = 0);
virtual ExprResult ActOnCXXOperatorFunctionIdExpr(Scope *S, virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr(Scope *S,
SourceLocation OperatorLoc, SourceLocation OperatorLoc,
OverloadedOperatorKind Op, OverloadedOperatorKind Op,
bool HasTrailingLParen, bool HasTrailingLParen,
const CXXScopeSpec &SS); const CXXScopeSpec &SS);
virtual ExprResult ActOnCXXConversionFunctionExpr(Scope *S, virtual OwningExprResult ActOnCXXConversionFunctionExpr(Scope *S,
SourceLocation OperatorLoc, SourceLocation OperatorLoc,
TypeTy *Ty, TypeTy *Ty,
bool HasTrailingLParen, bool HasTrailingLParen,
@ -960,29 +960,28 @@ public:
DeclRefExpr *BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc, DeclRefExpr *BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
bool TypeDependent, bool ValueDependent, bool TypeDependent, bool ValueDependent,
const CXXScopeSpec *SS = 0); const CXXScopeSpec *SS = 0);
ExprResult OwningExprResult
BuildAnonymousStructUnionMemberReference(SourceLocation Loc, BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
FieldDecl *Field, FieldDecl *Field,
Expr *BaseObjectExpr = 0, Expr *BaseObjectExpr = 0,
SourceLocation OpLoc = SourceLocation()); SourceLocation OpLoc = SourceLocation());
ExprResult ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, OwningExprResult ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
DeclarationName Name, DeclarationName Name,
bool HasTrailingLParen, bool HasTrailingLParen,
const CXXScopeSpec *SS, const CXXScopeSpec *SS,
bool ForceResolution = false); bool ForceResolution = false);
virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc, virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind); tok::TokenKind Kind);
virtual ExprResult ActOnNumericConstant(const Token &); virtual OwningExprResult ActOnNumericConstant(const Token &);
virtual ExprResult ActOnCharacterConstant(const Token &); virtual OwningExprResult ActOnCharacterConstant(const Token &);
virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
ExprTy *Val); ExprArg Val);
/// ActOnStringLiteral - The specified tokens were lexed as pasted string /// ActOnStringLiteral - The specified tokens were lexed as pasted string
/// fragments (e.g. "foo" "bar" L"baz"). /// 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. // Binary/Unary Operators. 'Tok' is the token for the operator.
virtual ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, virtual ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
tok::TokenKind Op, ExprTy *Input); tok::TokenKind Op, ExprTy *Input);

Просмотреть файл

@ -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 /// 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 /// multiple tokens. However, the common case is that StringToks points to one
/// string. /// string.
/// ///
Action::ExprResult Action::OwningExprResult
Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) { Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
assert(NumStringToks && "Must have at least one string!"); assert(NumStringToks && "Must have at least one string!");
StringLiteralParser Literal(StringToks, NumStringToks, PP); StringLiteralParser Literal(StringToks, NumStringToks, PP);
if (Literal.hadError) if (Literal.hadError)
return ExprResult(true); return ExprError();
llvm::SmallVector<SourceLocation, 4> StringTokLocs; llvm::SmallVector<SourceLocation, 4> StringTokLocs;
for (unsigned i = 0; i != NumStringToks; ++i) 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). // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
if (getLangOptions().CPlusPlus) if (getLangOptions().CPlusPlus)
StrTy.addConst(); StrTy.addConst();
// Get an array type for the string, according to C99 6.4.5. This includes // 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 // the nul terminator character as well as the string length for pascal
// strings. // strings.
StrTy = Context.getConstantArrayType(StrTy, StrTy = Context.getConstantArrayType(StrTy,
llvm::APInt(32, Literal.GetStringLength()+1), llvm::APInt(32, Literal.GetStringLength()+1),
ArrayType::Normal, 0); ArrayType::Normal, 0);
// Pass &StringTokLocs[0], StringTokLocs.size() to factory! // Pass &StringTokLocs[0], StringTokLocs.size() to factory!
return new StringLiteral(Literal.GetString(), Literal.GetStringLength(), return Owned(new StringLiteral(Literal.GetString(), Literal.GetStringLength(),
Literal.AnyWide, StrTy, Literal.AnyWide, StrTy,
StringToks[0].getLocation(), StringToks[0].getLocation(),
StringToks[NumStringToks-1].getLocation()); StringToks[NumStringToks-1].getLocation()));
} }
/// ShouldSnapshotBlockValueReference - Return true if a reference inside of /// 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, /// ActOnIdentifierExpr - The parser read an identifier in expression context,
/// validate it per-C99 6.5.1. HasTrailingLParen indicates whether this /// validate it per-C99 6.5.1. HasTrailingLParen indicates whether this
/// identifier is used in a function call context. /// 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. /// class or namespace that the identifier must be a member of.
Sema::ExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc, Sema::OwningExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
IdentifierInfo &II, IdentifierInfo &II,
bool HasTrailingLParen, bool HasTrailingLParen,
const CXXScopeSpec *SS) { const CXXScopeSpec *SS) {
return ActOnDeclarationNameExpr(S, Loc, &II, HasTrailingLParen, SS); return ActOnDeclarationNameExpr(S, Loc, &II, HasTrailingLParen, SS);
} }
@ -409,7 +409,7 @@ static ScopedDecl *getObjectForAnonymousRecordDecl(RecordDecl *Record) {
return 0; return 0;
} }
Sema::ExprResult Sema::OwningExprResult
Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
FieldDecl *Field, FieldDecl *Field,
Expr *BaseObjectExpr, Expr *BaseObjectExpr,
@ -484,15 +484,15 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
BaseObjectIsPointer = true; BaseObjectIsPointer = true;
} }
} else { } else {
return Diag(Loc, diag::err_invalid_member_use_in_static_method) return ExprError(Diag(Loc,diag::err_invalid_member_use_in_static_method)
<< Field->getDeclName(); << Field->getDeclName());
} }
ExtraQuals = MD->getTypeQualifiers(); ExtraQuals = MD->getTypeQualifiers();
} }
if (!BaseObjectExpr) if (!BaseObjectExpr)
return Diag(Loc, diag::err_invalid_non_static_member_use) return ExprError(Diag(Loc, diag::err_invalid_non_static_member_use)
<< Field->getDeclName(); << Field->getDeclName());
} }
// Build the implicit member references to the field of the // Build the implicit member references to the field of the
@ -514,7 +514,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
OpLoc = SourceLocation(); OpLoc = SourceLocation();
} }
return Result; return Owned(Result);
} }
/// ActOnDeclarationNameExpr - The parser has read some kind of name /// 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 /// 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 /// name even if it looks like a dependent name. This option is off by
/// default. /// default.
Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, Sema::OwningExprResult
DeclarationName Name, Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
bool HasTrailingLParen, DeclarationName Name, bool HasTrailingLParen,
const CXXScopeSpec *SS, const CXXScopeSpec *SS, bool ForceResolution) {
bool ForceResolution) {
if (S->getTemplateParamParent() && Name.getAsIdentifierInfo() && if (S->getTemplateParamParent() && Name.getAsIdentifierInfo() &&
HasTrailingLParen && !SS && !ForceResolution) { HasTrailingLParen && !SS && !ForceResolution) {
// We've seen something of the form // 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 // to represent this name. Then, if it turns out that none of the
// arguments are type-dependent, we'll force the resolution of the // arguments are type-dependent, we'll force the resolution of the
// dependent name at that point. // dependent name at that point.
return new CXXDependentNameExpr(Name.getAsIdentifierInfo(), return Owned(new CXXDependentNameExpr(Name.getAsIdentifierInfo(),
Context.DependentTy, Loc); Context.DependentTy, Loc));
} }
// Could be enum-constant, value decl, instance variable, etc. // 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()) { if (SS && !SS->isEmpty()) {
DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep()); DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
if (DC == 0) if (DC == 0)
return true; return ExprError();
Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC); Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC);
} else } else
Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S); Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S);
if (Lookup.isAmbiguous()) if (Lookup.isAmbiguous()) {
return DiagnoseAmbiguousLookup(Lookup, Name, Loc, DiagnoseAmbiguousLookup(Lookup, Name, Loc,
SS && SS->isSet()? SS->getRange() SS && SS->isSet() ? SS->getRange()
: SourceRange()); : SourceRange());
else return ExprError();
} else
D = Lookup.getAsDecl(); D = Lookup.getAsDecl();
// If this reference is in an Objective-C method, then ivar lookup happens as // 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 // FIXME: This should use a new expr for a direct reference, don't turn
// this into Self->ivar, just return a BareIVarExpr or something. // this into Self->ivar, just return a BareIVarExpr or something.
IdentifierInfo &II = Context.Idents.get("self"); IdentifierInfo &II = Context.Idents.get("self");
ExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false); OwningExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false);
ObjCIvarRefExpr *MRef= new ObjCIvarRefExpr(IV, IV->getType(), Loc, ObjCIvarRefExpr *MRef = new ObjCIvarRefExpr(IV, IV->getType(), Loc,
static_cast<Expr*>(SelfExpr.Val), true, true); static_cast<Expr*>(SelfExpr.release()),
true, true);
Context.setFieldDecl(IFace, IV, MRef); Context.setFieldDecl(IFace, IV, MRef);
return MRef; return Owned(MRef);
} }
} }
// Needed to implement property "super.method" notation. // Needed to implement property "super.method" notation.
if (SD == 0 && II->isStr("super")) { if (SD == 0 && II->isStr("super")) {
QualType T = Context.getPointerType(Context.getObjCInterfaceType( QualType T = Context.getPointerType(Context.getObjCInterfaceType(
getCurMethodDecl()->getClassInterface())); getCurMethodDecl()->getClassInterface()));
return new ObjCSuperExpr(Loc, T); return Owned(new ObjCSuperExpr(Loc, T));
} }
} }
if (D == 0) { 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, // If this name wasn't predeclared and if this is not a function call,
// diagnose the problem. // diagnose the problem.
if (SS && !SS->isEmpty()) if (SS && !SS->isEmpty())
return Diag(Loc, diag::err_typecheck_no_member) return ExprError(Diag(Loc, diag::err_typecheck_no_member)
<< Name << SS->getRange(); << Name << SS->getRange());
else if (Name.getNameKind() == DeclarationName::CXXOperatorName || else if (Name.getNameKind() == DeclarationName::CXXOperatorName ||
Name.getNameKind() == DeclarationName::CXXConversionFunctionName) Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
return Diag(Loc, diag::err_undeclared_use) << Name.getAsString(); return ExprError(Diag(Loc, diag::err_undeclared_use)
<< Name.getAsString());
else 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 (FieldDecl *FD = dyn_cast<FieldDecl>(D))
if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion()) if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion())
return BuildAnonymousStructUnionMemberReference(Loc, FD); return BuildAnonymousStructUnionMemberReference(Loc, FD);
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) { if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
if (!MD->isStatic()) { if (!MD->isStatic()) {
// C++ [class.mfct.nonstatic]p2: // C++ [class.mfct.nonstatic]p2:
@ -678,8 +680,8 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// Build the implicit member access expression. // Build the implicit member access expression.
Expr *This = new CXXThisExpr(SourceLocation(), Expr *This = new CXXThisExpr(SourceLocation(),
MD->getThisType(Context)); MD->getThisType(Context));
return new MemberExpr(This, true, cast<NamedDecl>(D), return Owned(new MemberExpr(This, true, cast<NamedDecl>(D),
SourceLocation(), MemberType); SourceLocation(), MemberType));
} }
} }
} }
@ -689,34 +691,35 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) { if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
if (MD->isStatic()) if (MD->isStatic())
// "invalid use of member 'x' in static member function" // "invalid use of member 'x' in static member function"
return Diag(Loc, diag::err_invalid_member_use_in_static_method) return ExprError(Diag(Loc,diag::err_invalid_member_use_in_static_method)
<< FD->getDeclName(); << FD->getDeclName());
} }
// Any other ways we could have found the field in a well-formed // Any other ways we could have found the field in a well-formed
// program would have been turned into implicit member expressions // program would have been turned into implicit member expressions
// above. // above.
return Diag(Loc, diag::err_invalid_non_static_member_use) return ExprError(Diag(Loc, diag::err_invalid_non_static_member_use)
<< FD->getDeclName(); << FD->getDeclName());
} }
if (isa<TypedefDecl>(D)) 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)) 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)) 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. // Make the DeclRefExpr or BlockDeclRefExpr for the decl.
if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D)) 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); ValueDecl *VD = cast<ValueDecl>(D);
// check if referencing an identifier with __attribute__((deprecated)). // check if referencing an identifier with __attribute__((deprecated)).
if (VD->getAttr<DeprecatedAttr>()) 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 (VarDecl *Var = dyn_cast<VarDecl>(VD)) {
if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) { if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
Scope *CheckS = S; Scope *CheckS = S;
@ -724,9 +727,11 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
if (CheckS->isWithinElse() && if (CheckS->isWithinElse() &&
CheckS->getControlParent()->isDeclScope(Var)) { CheckS->getControlParent()->isDeclScope(Var)) {
if (Var->getType()->isBooleanType()) if (Var->getType()->isBooleanType())
Diag(Loc, diag::warn_value_always_false) << Var->getDeclName(); ExprError(Diag(Loc, diag::warn_value_always_false)
<< Var->getDeclName());
else else
Diag(Loc, diag::warn_value_always_zero) << Var->getDeclName(); ExprError(Diag(Loc, diag::warn_value_always_zero)
<< Var->getDeclName());
break; break;
} }
@ -740,8 +745,8 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// Only create DeclRefExpr's for valid Decl's. // Only create DeclRefExpr's for valid Decl's.
if (VD->isInvalidDecl()) if (VD->isInvalidDecl())
return true; return ExprError();
// If the identifier reference is inside a block, and it refers to a value // 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 // that is outside the block, create a BlockDeclRefExpr instead of a
// DeclRefExpr. This ensures the value is treated as a copy-in snapshot when // 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)) { if (CurBlock && ShouldSnapshotBlockValueReference(CurBlock, VD)) {
// The BlocksAttr indicates the variable is bound by-reference. // The BlocksAttr indicates the variable is bound by-reference.
if (VD->getAttr<BlocksAttr>()) if (VD->getAttr<BlocksAttr>())
return new BlockDeclRefExpr(VD, VD->getType().getNonReferenceType(), return Owned(new BlockDeclRefExpr(VD, VD->getType().getNonReferenceType(),
Loc, true); Loc, true));
// Variable will be bound by-copy, make it const within the closure. // Variable will be bound by-copy, make it const within the closure.
VD->getType().addConst(); VD->getType().addConst();
return new BlockDeclRefExpr(VD, VD->getType().getNonReferenceType(), return Owned(new BlockDeclRefExpr(VD, VD->getType().getNonReferenceType(),
Loc, false); Loc, false));
} }
// If this reference is not in a block or if the referenced variable is // If this reference is not in a block or if the referenced variable is
// within the block, create a normal DeclRefExpr. // within the block, create a normal DeclRefExpr.
@ -807,14 +812,14 @@ Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// (FIXME!). // (FIXME!).
} }
return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, return Owned(BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc,
TypeDependent, ValueDependent, SS); TypeDependent, ValueDependent, SS));
} }
Sema::ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind) { tok::TokenKind Kind) {
PredefinedExpr::IdentType IT; PredefinedExpr::IdentType IT;
switch (Kind) { switch (Kind) {
default: assert(0 && "Unknown simple primary expr!"); default: assert(0 && "Unknown simple primary expr!");
case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2] 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. // __PRETTY_FUNCTION__ -> "top level", the others produce an empty string.
Length = IT == PredefinedExpr::PrettyFunction ? strlen("top level") : 0; Length = IT == PredefinedExpr::PrettyFunction ? strlen("top level") : 0;
} }
llvm::APInt LengthI(32, Length + 1); llvm::APInt LengthI(32, Length + 1);
QualType ResTy = Context.CharTy.getQualifiedType(QualType::Const); QualType ResTy = Context.CharTy.getQualifiedType(QualType::Const);
ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0); 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; llvm::SmallString<16> CharBuffer;
CharBuffer.resize(Tok.getLength()); CharBuffer.resize(Tok.getLength());
const char *ThisTokBegin = &CharBuffer[0]; const char *ThisTokBegin = &CharBuffer[0];
unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin); unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
CharLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, CharLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
Tok.getLocation(), PP); Tok.getLocation(), PP);
if (Literal.hadError()) if (Literal.hadError())
return ExprResult(true); return ExprError();
QualType type = getLangOptions().CPlusPlus ? Context.CharTy : Context.IntTy; QualType type = getLangOptions().CPlusPlus ? Context.CharTy : Context.IntTy;
return new CharacterLiteral(Literal.getValue(), Literal.isWide(), type, return Owned(new CharacterLiteral(Literal.getValue(), Literal.isWide(), type,
Tok.getLocation()); Tok.getLocation()));
} }
Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) { Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
// Fast path for a single digit (which is quite common). A single digit // Fast path for a single digit (which is quite common). A single digit
// cannot have a trigraph, escaped newline, radix prefix, or type suffix. // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
if (Tok.getLength() == 1) { if (Tok.getLength() == 1) {
const char Val = PP.getSpelledCharacterAt(Tok.getLocation()); const char Val = PP.getSpelledCharacterAt(Tok.getLocation());
unsigned IntSize = Context.Target.getIntWidth(); unsigned IntSize = Context.Target.getIntWidth();
return ExprResult(new IntegerLiteral(llvm::APInt(IntSize, Val-'0'), return Owned(new IntegerLiteral(llvm::APInt(IntSize, Val-'0'),
Context.IntTy, Context.IntTy, Tok.getLocation()));
Tok.getLocation()));
} }
llvm::SmallString<512> IntegerBuffer; llvm::SmallString<512> IntegerBuffer;
// Add padding so that NumericLiteralParser can overread by one character. // Add padding so that NumericLiteralParser can overread by one character.
IntegerBuffer.resize(Tok.getLength()+1); IntegerBuffer.resize(Tok.getLength()+1);
const char *ThisTokBegin = &IntegerBuffer[0]; const char *ThisTokBegin = &IntegerBuffer[0];
// Get the spelling of the token, which eliminates trigraphs, etc. // Get the spelling of the token, which eliminates trigraphs, etc.
unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin); unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
Tok.getLocation(), PP); Tok.getLocation(), PP);
if (Literal.hadError) if (Literal.hadError)
return ExprResult(true); return ExprError();
Expr *Res; Expr *Res;
if (Literal.isFloatingLiteral()) { if (Literal.isFloatingLiteral()) {
QualType Ty; QualType Ty;
if (Literal.isFloat) if (Literal.isFloat)
@ -900,9 +904,9 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
bool isExact = false; bool isExact = false;
Res = new FloatingLiteral(Literal.GetFloatValue(Format, &isExact), &isExact, Res = new FloatingLiteral(Literal.GetFloatValue(Format, &isExact), &isExact,
Ty, Tok.getLocation()); Ty, Tok.getLocation());
} else if (!Literal.isIntegerLiteral()) { } else if (!Literal.isIntegerLiteral()) {
return ExprResult(true); return ExprError();
} else { } else {
QualType Ty; QualType Ty;
@ -913,7 +917,7 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
// Get the value in the widest-possible width. // Get the value in the widest-possible width.
llvm::APInt ResultVal(Context.Target.getIntMaxTWidth(), 0); llvm::APInt ResultVal(Context.Target.getIntMaxTWidth(), 0);
if (Literal.GetIntegerValue(ResultVal)) { if (Literal.GetIntegerValue(ResultVal)) {
// If this value didn't fit into uintmax_t, warn and force to ull. // If this value didn't fit into uintmax_t, warn and force to ull.
Diag(Tok.getLocation(), diag::warn_integer_too_large); Diag(Tok.getLocation(), diag::warn_integer_too_large);
@ -923,7 +927,7 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
} else { } else {
// If this value fits into a ULL, try to figure out what else it fits into // 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. // according to the rules of C99 6.4.4.1p5.
// Octal, Hexadecimal, and integers with a U suffix are allowed to // Octal, Hexadecimal, and integers with a U suffix are allowed to
// be an unsigned int. // be an unsigned int.
bool AllowUnsigned = Literal.isUnsigned || Literal.getRadix() != 10; bool AllowUnsigned = Literal.isUnsigned || Literal.getRadix() != 10;
@ -933,7 +937,7 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
if (!Literal.isLong && !Literal.isLongLong) { if (!Literal.isLong && !Literal.isLongLong) {
// Are int/unsigned possibilities? // Are int/unsigned possibilities?
unsigned IntSize = Context.Target.getIntWidth(); unsigned IntSize = Context.Target.getIntWidth();
// Does it fit in a unsigned int? // Does it fit in a unsigned int?
if (ResultVal.isIntN(IntSize)) { if (ResultVal.isIntN(IntSize)) {
// Does it fit in a signed int? // Does it fit in a signed int?
@ -944,11 +948,11 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
Width = IntSize; Width = IntSize;
} }
} }
// Are long/unsigned long possibilities? // Are long/unsigned long possibilities?
if (Ty.isNull() && !Literal.isLongLong) { if (Ty.isNull() && !Literal.isLongLong) {
unsigned LongSize = Context.Target.getLongWidth(); unsigned LongSize = Context.Target.getLongWidth();
// Does it fit in a unsigned long? // Does it fit in a unsigned long?
if (ResultVal.isIntN(LongSize)) { if (ResultVal.isIntN(LongSize)) {
// Does it fit in a signed long? // Does it fit in a signed long?
@ -958,12 +962,12 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
Ty = Context.UnsignedLongTy; Ty = Context.UnsignedLongTy;
Width = LongSize; Width = LongSize;
} }
} }
// Finally, check long long if needed. // Finally, check long long if needed.
if (Ty.isNull()) { if (Ty.isNull()) {
unsigned LongLongSize = Context.Target.getLongLongWidth(); unsigned LongLongSize = Context.Target.getLongLongWidth();
// Does it fit in a unsigned long long? // Does it fit in a unsigned long long?
if (ResultVal.isIntN(LongLongSize)) { if (ResultVal.isIntN(LongLongSize)) {
// Does it fit in a signed long long? // Does it fit in a signed long long?
@ -974,7 +978,7 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
Width = LongLongSize; Width = LongLongSize;
} }
} }
// If we still couldn't decide a type, we probably have something that // If we still couldn't decide a type, we probably have something that
// does not fit in a signed long long, but has no U suffix. // does not fit in a signed long long, but has no U suffix.
if (Ty.isNull()) { if (Ty.isNull()) {
@ -982,26 +986,26 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
Ty = Context.UnsignedLongLongTy; Ty = Context.UnsignedLongLongTy;
Width = Context.Target.getLongLongWidth(); Width = Context.Target.getLongLongWidth();
} }
if (ResultVal.getBitWidth() != Width) if (ResultVal.getBitWidth() != Width)
ResultVal.trunc(Width); ResultVal.trunc(Width);
} }
Res = new IntegerLiteral(ResultVal, Ty, Tok.getLocation()); Res = new IntegerLiteral(ResultVal, Ty, Tok.getLocation());
} }
// If this is an imaginary literal, create the ImaginaryLiteral wrapper. // If this is an imaginary literal, create the ImaginaryLiteral wrapper.
if (Literal.isImaginary) if (Literal.isImaginary)
Res = new ImaginaryLiteral(Res, Context.getComplexType(Res->getType())); Res = new ImaginaryLiteral(Res, Context.getComplexType(Res->getType()));
return Res; return Owned(Res);
} }
Action::ExprResult Sema::ActOnParenExpr(SourceLocation L, SourceLocation R, Action::OwningExprResult Sema::ActOnParenExpr(SourceLocation L,
ExprTy *Val) { SourceLocation R, ExprArg Val) {
Expr *E = (Expr *)Val; Expr *E = (Expr *)Val.release();
assert((E != 0) && "ActOnParenExpr() missing expr"); assert((E != 0) && "ActOnParenExpr() missing expr");
return new ParenExpr(L, R, E); return Owned(new ParenExpr(L, R, E));
} }
/// The UsualUnaryConversions() function is *not* called by this routine. /// The UsualUnaryConversions() function is *not* called by this routine.
@ -1477,8 +1481,9 @@ ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc,
// We may have found a field within an anonymous union or struct // We may have found a field within an anonymous union or struct
// (C++ [class.union]). // (C++ [class.union]).
if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion()) if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion())
return BuildAnonymousStructUnionMemberReference(MemberLoc, FD, return BuildAnonymousStructUnionMemberReference(MemberLoc, FD,
BaseExpr, OpLoc); BaseExpr, OpLoc)
.release();
// Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref] // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
// FIXME: Handle address space modifiers // FIXME: Handle address space modifiers
@ -1743,16 +1748,17 @@ Sema::ActOnCallExpr(Scope *S, ExprTy *fn, SourceLocation LParenLoc,
else { else {
// Resolve the CXXDependentNameExpr to an actual identifier; // Resolve the CXXDependentNameExpr to an actual identifier;
// it wasn't really a dependent name after all. // it wasn't really a dependent name after all.
ExprResult Resolved OwningExprResult Resolved
= ActOnDeclarationNameExpr(S, FnName->getLocation(), FnName->getName(), = ActOnDeclarationNameExpr(S, FnName->getLocation(),
FnName->getName(),
/*HasTrailingLParen=*/true, /*HasTrailingLParen=*/true,
/*SS=*/0, /*SS=*/0,
/*ForceResolution=*/true); /*ForceResolution=*/true);
if (Resolved.isInvalid) if (Resolved.isInvalid())
return true; return true;
else { else {
delete Fn; delete Fn;
Fn = (Expr *)Resolved.Val; Fn = (Expr *)Resolved.release();
} }
} }
} else } else

Просмотреть файл

@ -26,7 +26,7 @@ using namespace clang;
/// very similar to ActOnIdentifierExpr, except that instead of /// very similar to ActOnIdentifierExpr, except that instead of
/// providing an identifier the parser provides the type of the /// providing an identifier the parser provides the type of the
/// conversion function. /// conversion function.
Sema::ExprResult Sema::OwningExprResult
Sema::ActOnCXXConversionFunctionExpr(Scope *S, SourceLocation OperatorLoc, Sema::ActOnCXXConversionFunctionExpr(Scope *S, SourceLocation OperatorLoc,
TypeTy *Ty, bool HasTrailingLParen, TypeTy *Ty, bool HasTrailingLParen,
const CXXScopeSpec &SS) { const CXXScopeSpec &SS) {
@ -34,7 +34,7 @@ Sema::ActOnCXXConversionFunctionExpr(Scope *S, SourceLocation OperatorLoc,
QualType ConvTypeCanon = Context.getCanonicalType(ConvType); QualType ConvTypeCanon = Context.getCanonicalType(ConvType);
DeclarationName ConvName DeclarationName ConvName
= Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon); = Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon);
return ActOnDeclarationNameExpr(S, OperatorLoc, ConvName, HasTrailingLParen, return ActOnDeclarationNameExpr(S, OperatorLoc, ConvName, HasTrailingLParen,
&SS); &SS);
} }
@ -43,7 +43,7 @@ Sema::ActOnCXXConversionFunctionExpr(Scope *S, SourceLocation OperatorLoc,
/// similar to ActOnIdentifierExpr, except that instead of providing /// similar to ActOnIdentifierExpr, except that instead of providing
/// an identifier the parser provides the kind of overloaded /// an identifier the parser provides the kind of overloaded
/// operator that was parsed. /// operator that was parsed.
Sema::ExprResult Sema::OwningExprResult
Sema::ActOnCXXOperatorFunctionIdExpr(Scope *S, SourceLocation OperatorLoc, Sema::ActOnCXXOperatorFunctionIdExpr(Scope *S, SourceLocation OperatorLoc,
OverloadedOperatorKind Op, OverloadedOperatorKind Op,
bool HasTrailingLParen, bool HasTrailingLParen,