diff options
| author | Chris Lattner <sabre@nondot.org> | 2007-08-30 15:51:11 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2007-08-30 15:51:11 +0000 |
| commit | 687d609f04f4becd57897c2048764166b61c61a8 (patch) | |
| tree | 2a72e46c3cf6c180e5e69196ddfd1ae13576bd2e | |
| parent | fec2519b4bd2734db008f2050d15755e3a250098 (diff) | |
| download | bcm5719-llvm-687d609f04f4becd57897c2048764166b61c61a8.tar.gz bcm5719-llvm-687d609f04f4becd57897c2048764166b61c61a8.zip | |
add an action callback for __builtin_offsetof
llvm-svn: 41606
| -rw-r--r-- | clang/Parse/ParseExpr.cpp | 50 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Action.h | 19 |
2 files changed, 57 insertions, 12 deletions
diff --git a/clang/Parse/ParseExpr.cpp b/clang/Parse/ParseExpr.cpp index 46bcd67f3f2..87971588dba 100644 --- a/clang/Parse/ParseExpr.cpp +++ b/clang/Parse/ParseExpr.cpp @@ -773,40 +773,66 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() { ParseTypeName(); break; - case tok::kw___builtin_offsetof: - ParseTypeName(); + case tok::kw___builtin_offsetof: { + TypeTy *Ty = ParseTypeName(); if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) return ExprResult(true); // We must have at least one identifier here. - if (ExpectAndConsume(tok::identifier, diag::err_expected_ident, "", - tok::r_paren)) - return ExprResult(true); + if (Tok.getKind() != tok::identifier) { + Diag(Tok, diag::err_expected_ident); + SkipUntil(tok::r_paren); + return true; + } + + // Keep track of the various subcomponents we see. + llvm::SmallVector<Action::OffsetOfComponent, 4> Comps; + + Comps.push_back(Action::OffsetOfComponent()); + Comps.back().isBrackets = false; + Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); + Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); while (1) { if (Tok.getKind() == tok::period) { // offsetof-member-designator: offsetof-member-designator '.' identifier - ConsumeToken(); + Comps.push_back(Action::OffsetOfComponent()); + Comps.back().isBrackets = false; + Comps.back().LocStart = ConsumeToken(); + + if (Tok.getKind() != tok::identifier) { + Diag(Tok, diag::err_expected_ident); + SkipUntil(tok::r_paren); + return true; + } + Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); + Comps.back().LocEnd = ConsumeToken(); - if (ExpectAndConsume(tok::identifier, diag::err_expected_ident, "", - tok::r_paren)) - return ExprResult(true); } else if (Tok.getKind() == tok::l_square) { // offsetof-member-designator: offsetof-member-design '[' expression ']' - SourceLocation LSquareLoc = ConsumeBracket(); + Comps.push_back(Action::OffsetOfComponent()); + Comps.back().isBrackets = true; + Comps.back().LocStart = ConsumeBracket(); Res = ParseExpression(); if (Res.isInvalid) { SkipUntil(tok::r_paren); return Res; } + Comps.back().U.E = Res.Val; - MatchRHSPunctuation(tok::r_square, LSquareLoc); + Comps.back().LocEnd = + MatchRHSPunctuation(tok::r_square, Comps.back().LocStart); + } else if (Tok.getKind() == tok::r_paren) { + return Actions.ParseBuiltinOffsetOf(StartLoc, Ty, &Comps[0], + Comps.size(), ConsumeParen()); } else { - break; + // Error occurred. + return ExprResult(true); } } break; + } case tok::kw___builtin_choose_expr: { ExprResult Cond = ParseAssignmentExpression(); if (Cond.isInvalid) { diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 1ddbe85fb4d..1f84e0d86f1 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -375,6 +375,25 @@ public: SourceLocation RPLoc) { // "({..})" return 0; } + + // __builtin_offsetof(type, identifier(.identifier|[expr])*) + struct OffsetOfComponent { + SourceLocation LocStart, LocEnd; + bool isBrackets; // true if [expr], false if .ident + union { + IdentifierInfo *IdentInfo; + ExprTy *E; + } U; + }; + + virtual ExprResult ParseBuiltinOffsetOf(SourceLocation BuiltinLoc, + TypeTy *Arg1, + OffsetOfComponent *CompPtr, + unsigned NumComponents, + SourceLocation RParenLoc) { + return 0; + } + // __builtin_types_compatible_p(type1, type2) virtual ExprResult ParseTypesCompatibleExpr(SourceLocation BuiltinLoc, TypeTy *arg1, TypeTy *arg2, |

