зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
f512e82f56
Коммит
cd965b97cf
|
@ -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,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче