[cfe-commits] r72255 - in /cfe/trunk: lib/AST/Type.cpp lib/Parse/ParseDecl.cpp test/Parser/cxx-template-decl.cpp test/Parser/typeof.c test/Sema/exprs.c
Argiris Kirtzidis
akyrtzi at gmail.com
Fri May 22 03:22:23 PDT 2009
Author: akirtzidis
Date: Fri May 22 05:22:18 2009
New Revision: 72255
URL: http://llvm.org/viewvc/llvm-project?rev=72255&view=rev
Log:
Parse typeof-specifier the same way as sizeof/alignof are parsed.
-Makes typeof consistent with sizeof/alignof
-Fixes a bug when '>' is in a typeof expression, inside a template type param:
A<typeof(x>1)> a;
Modified:
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/test/Parser/cxx-template-decl.cpp
cfe/trunk/test/Parser/typeof.c
cfe/trunk/test/Sema/exprs.c
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=72255&r1=72254&r2=72255&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri May 22 05:22:18 2009
@@ -1324,7 +1324,7 @@
std::string Str;
llvm::raw_string_ostream s(Str);
getUnderlyingExpr()->printPretty(s);
- InnerString = "typeof(" + s.str() + ")" + InnerString;
+ InnerString = "typeof " + s.str() + InnerString;
}
void TypeOfType::getAsStringInternal(std::string &InnerString) const {
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=72255&r1=72254&r2=72255&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri May 22 05:22:18 2009
@@ -2651,68 +2651,59 @@
const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
SourceLocation StartLoc = ConsumeToken();
+ // If the operand doesn't start with an '(', it must be an expression.
+ OwningExprResult Operand(Actions);
if (Tok.isNot(tok::l_paren)) {
if (!getLang().CPlusPlus) {
Diag(Tok, diag::err_expected_lparen_after_id) << BuiltinII;
return;
}
-
- OwningExprResult Result(ParseCastExpression(true/*isUnaryExpression*/));
- if (Result.isInvalid()) {
- DS.SetTypeSpecError();
- return;
- }
-
- const char *PrevSpec = 0;
- // Check for duplicate type specifiers.
- if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
- Result.release()))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
-
+ Operand = ParseCastExpression(true/*isUnaryExpression*/);
// FIXME: Not accurate, the range gets one token more than it should.
DS.SetRangeEnd(Tok.getLocation());
- return;
- }
-
- SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
-
- if (isTypeIdInParens()) {
- Action::TypeResult Ty = ParseTypeName();
-
- assert((Ty.isInvalid() || Ty.get()) &&
- "Parser::ParseTypeofSpecifier(): missing type");
- if (Tok.isNot(tok::r_paren)) {
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- return;
- }
- RParenLoc = ConsumeParen();
+ } else {
+ // If it starts with a '(', we know that it is either a parenthesized
+ // type-name, or it is a unary-expression that starts with a compound
+ // literal, or starts with a primary-expression that is a parenthesized
+ // expression.
+ ParenParseOption ExprType = CastExpr;
+ TypeTy *CastTy;
+ SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
+ Operand = ParseParenExpression(ExprType, CastTy, RParenLoc);
+ DS.SetRangeEnd(RParenLoc);
+
+ // If ParseParenExpression parsed a '(typename)' sequence only, then this is
+ // typeof a type. Otherwise, it is typeof an expression.
+ if (ExprType == CastExpr) {
+ if (!CastTy) {
+ DS.SetTypeSpecError();
+ return;
+ }
- if (Ty.isInvalid())
- DS.SetTypeSpecError();
- else {
const char *PrevSpec = 0;
// Check for duplicate type specifiers (e.g. "int typeof(int)").
- if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
- Ty.get()))
+ if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
+ CastTy))
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
- }
- } else { // we have an expression.
- OwningExprResult Result(ParseExpression());
-
- if (Result.isInvalid() || Tok.isNot(tok::r_paren)) {
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- DS.SetTypeSpecError();
return;
}
- RParenLoc = ConsumeParen();
- const char *PrevSpec = 0;
- // Check for duplicate type specifiers (e.g. "int typeof(int)").
- if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
- Result.release()))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+
+ // If this is a parenthesized expression, it is the start of a
+ // unary-expression, but doesn't include any postfix pieces. Parse these
+ // now if present.
+ Operand = ParsePostfixExpressionSuffix(move(Operand));
}
- DS.SetRangeEnd(RParenLoc);
-}
+ // If we get here, the operand to the typeof was an expresion.
+ if (Operand.isInvalid()) {
+ DS.SetTypeSpecError();
+ return;
+ }
+ const char *PrevSpec = 0;
+ // Check for duplicate type specifiers (e.g. "int typeof(int)").
+ if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
+ Operand.release()))
+ Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+}
Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=72255&r1=72254&r2=72255&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-template-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-decl.cpp Fri May 22 05:22:18 2009
@@ -75,3 +75,8 @@
template<typename T>
const T& min(const T&, const T&);
+
+void f2() {
+ int x;
+ A< typeof(x>1) > a;
+}
Modified: cfe/trunk/test/Parser/typeof.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/typeof.c?rev=72255&r1=72254&r2=72255&view=diff
==============================================================================
--- cfe/trunk/test/Parser/typeof.c (original)
+++ cfe/trunk/test/Parser/typeof.c Fri May 22 05:22:18 2009
@@ -11,7 +11,7 @@
typeof(TInt) anInt;
short TInt eee; // expected-error{{expected ';' at end of declaration}}
void ary[7] fff; // expected-error{{array has incomplete element type 'void'}} expected-error{{expected ';' at end of declaration}}
- typeof(void ary[7]) anIntError; // expected-error{{expected ')'}} expected-note {{to match this '('}} expected-warning {{type specifier missing, defaults to 'int'}}
+ typeof(void ary[7]) anIntError; // expected-error{{expected ')'}} expected-note {{to match this '('}} expected-error {{variable has incomplete type 'typeof(void)' (aka 'void')}}
typeof(const int) aci;
const typeof (*pi) aConstInt;
int xx;
Modified: cfe/trunk/test/Sema/exprs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/exprs.c?rev=72255&r1=72254&r2=72255&view=diff
==============================================================================
--- cfe/trunk/test/Sema/exprs.c (original)
+++ cfe/trunk/test/Sema/exprs.c Fri May 22 05:22:18 2009
@@ -79,7 +79,7 @@
struct mystruct {int A; };
void test11(struct mystruct P, float F) {
- MYMAX(P, F); // expected-error {{invalid operands to binary expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka 'float'))}}
+ MYMAX(P, F); // expected-error {{invalid operands to binary expression ('typeof (P)' (aka 'struct mystruct') and 'typeof (F)' (aka 'float'))}}
}
// PR3753
More information about the cfe-commits
mailing list