Add (basic) expression AST representation capabilities for int/fp/binops/condexpr.

Add callbacks for same.
Add "full locinfo" mode.

llvm-svn: 38939
This commit is contained in:
Chris Lattner 2006-08-23 05:17:46 +00:00
parent c11438cee1
commit 9b6d4cb90e
12 changed files with 371 additions and 31 deletions

View File

@ -19,15 +19,15 @@ using namespace clang;
/// Interface to the Builder.cpp file.
///
Action *CreateASTBuilderActions();
Action *CreateASTBuilderActions(bool FullLocInfo);
namespace {
class ASTStreamer {
Parser P;
public:
ASTStreamer(Preprocessor &PP, unsigned MainFileID)
: P(PP, *CreateASTBuilderActions()) {
ASTStreamer(Preprocessor &PP, unsigned MainFileID, bool FullLocInfo)
: P(PP, *CreateASTBuilderActions(FullLocInfo)) {
PP.EnterSourceFile(MainFileID, 0, true);
// Initialize the parser.
@ -59,8 +59,9 @@ namespace {
/// ASTStreamer_Init - Create an ASTStreamer with the specified preprocessor
/// and FileID.
ASTStreamerTy *llvm::clang::ASTStreamer_Init(Preprocessor &PP,
unsigned MainFileID) {
return new ASTStreamer(PP, MainFileID);
unsigned MainFileID,
bool FullLocInfo) {
return new ASTStreamer(PP, MainFileID, FullLocInfo);
}
/// ASTStreamer_ReadTopLevelDecl - Parse and return one top-level declaration. This

View File

@ -13,9 +13,11 @@
//===----------------------------------------------------------------------===//
#include "clang/Parse/Action.h"
#include "clang/Parse/Scope.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Parse/Scope.h"
#include "clang/Lex/IdentifierTable.h"
#include "clang/Lex/LexerToken.h"
#include "llvm/Support/Visibility.h"
using namespace llvm;
using namespace clang;
@ -23,7 +25,11 @@ using namespace clang;
/// ASTBuilder
namespace {
class VISIBILITY_HIDDEN ASTBuilder : public Action {
/// FullLocInfo - If this is true, the ASTBuilder constructs AST Nodes that
/// capture maximal location information for each source-language construct.
bool FullLocInfo;
public:
ASTBuilder(bool fullLocInfo) : FullLocInfo(fullLocInfo) {}
//===--------------------------------------------------------------------===//
// Symbol table tracking callbacks.
//
@ -31,6 +37,20 @@ public:
virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
ExprTy *Init);
virtual void PopScope(SourceLocation Loc, Scope *S);
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks.
virtual ExprTy *ParseIntegerConstant(const LexerToken &Tok);
virtual ExprTy *ParseFloatingConstant(const LexerToken &Tok);
// Binary Operators. 'Tok' is the token
virtual ExprTy *ParseBinOp(const LexerToken &Tok, ExprTy *LHS, ExprTy *RHS);
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
/// in the case of a the GNU conditional expr extension.
virtual ExprTy *ParseConditionalOp(SourceLocation QuestionLoc,
SourceLocation ColonLoc,
ExprTy *Cond, ExprTy *LHS, ExprTy *RHS);
};
} // end anonymous namespace
@ -75,11 +95,79 @@ void ASTBuilder::PopScope(SourceLocation Loc, Scope *S) {
}
}
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks.
//===--------------------------------------------------------------------===//
ASTBuilder::ExprTy *ASTBuilder::ParseIntegerConstant(const LexerToken &Tok) {
return new IntegerConstant();
}
ASTBuilder::ExprTy *ASTBuilder::ParseFloatingConstant(const LexerToken &Tok) {
return new FloatingConstant();
}
// Binary Operators. 'Tok' is the token for the operator.
ASTBuilder::ExprTy *ASTBuilder::ParseBinOp(const LexerToken &Tok, ExprTy *LHS,
ExprTy *RHS) {
BinaryOperator::Opcode Opc;
switch (Tok.getKind()) {
default: assert(0 && "Unknown binop!");
case tok::star: Opc = BinaryOperator::Mul; break;
case tok::slash: Opc = BinaryOperator::Div; break;
case tok::percent: Opc = BinaryOperator::Rem; break;
case tok::plus: Opc = BinaryOperator::Add; break;
case tok::minus: Opc = BinaryOperator::Sub; break;
case tok::lessless: Opc = BinaryOperator::Shl; break;
case tok::greatergreater: Opc = BinaryOperator::Shr; break;
case tok::lessequal: Opc = BinaryOperator::LE; break;
case tok::less: Opc = BinaryOperator::LT; break;
case tok::greaterequal: Opc = BinaryOperator::GE; break;
case tok::greater: Opc = BinaryOperator::GT; break;
case tok::exclaimequal: Opc = BinaryOperator::NE; break;
case tok::equalequal: Opc = BinaryOperator::EQ; break;
case tok::amp: Opc = BinaryOperator::And; break;
case tok::caret: Opc = BinaryOperator::Xor; break;
case tok::pipe: Opc = BinaryOperator::Or; break;
case tok::ampamp: Opc = BinaryOperator::LAnd; break;
case tok::pipepipe: Opc = BinaryOperator::LOr; break;
case tok::equal: Opc = BinaryOperator::Assign; break;
case tok::starequal: Opc = BinaryOperator::MulAssign; break;
case tok::slashequal: Opc = BinaryOperator::DivAssign; break;
case tok::percentequal: Opc = BinaryOperator::RemAssign; break;
case tok::plusequal: Opc = BinaryOperator::AddAssign; break;
case tok::minusequal: Opc = BinaryOperator::SubAssign; break;
case tok::lesslessequal: Opc = BinaryOperator::ShlAssign; break;
case tok::greatergreaterequal: Opc = BinaryOperator::ShrAssign; break;
case tok::ampequal: Opc = BinaryOperator::AndAssign; break;
case tok::caretequal: Opc = BinaryOperator::XorAssign; break;
case tok::pipeequal: Opc = BinaryOperator::OrAssign; break;
case tok::comma: Opc = BinaryOperator::Comma; break;
}
if (!FullLocInfo)
return new BinaryOperator((Expr*)LHS, (Expr*)RHS, Opc);
else
return new BinaryOperatorLOC((Expr*)LHS, Tok.getLocation(), (Expr*)RHS,Opc);
}
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
/// in the case of a the GNU conditional expr extension.
ASTBuilder::ExprTy *ASTBuilder::ParseConditionalOp(SourceLocation QuestionLoc,
SourceLocation ColonLoc,
ExprTy *Cond, ExprTy *LHS,
ExprTy *RHS) {
if (!FullLocInfo)
return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
else
return new ConditionalOperatorLOC((Expr*)Cond, QuestionLoc, (Expr*)LHS,
ColonLoc, (Expr*)RHS);
}
/// Interface to the Builder.cpp file.
///
Action *CreateASTBuilderActions() {
return new ASTBuilder();
Action *CreateASTBuilderActions(bool FullLocInfo) {
return new ASTBuilder(FullLocInfo);
}

View File

@ -633,7 +633,7 @@ static void ParseFile(Preprocessor &PP, Action *PA, unsigned MainFileID) {
//===----------------------------------------------------------------------===//
static void PrintASTs(Preprocessor &PP, unsigned MainFileID) {
ASTStreamerTy *Streamer = ASTStreamer_Init(PP, MainFileID);
ASTStreamerTy *Streamer = ASTStreamer_Init(PP, MainFileID, true);
while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
std::cerr << "Read decl!\n";

View File

@ -288,7 +288,8 @@ ParseAssignmentExpressionWithLeadingStar(const LexerToken &Tok) {
Parser::ExprResult
Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
SourceLocation ColonLoc;
while (1) {
// If this token has a lower precedence than we are allowed to parse (e.g.
// because we are called recursively, or because the token is not a binop),
@ -324,6 +325,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
}
// Eat the colon.
ColonLoc = Tok.getLocation();
ConsumeToken();
}
@ -355,7 +357,12 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
}
assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
// TODO: combine the LHS and RHS into the LHS (e.g. build AST).
// Combine the LHS and RHS into the LHS (e.g. build AST).
if (NextTokPrec != prec::Conditional)
LHS = Actions.ParseBinOp(OpToken, LHS.Val, RHS.Val);
else
LHS = Actions.ParseConditionalOp(OpToken.getLocation(), ColonLoc,
LHS.Val, TernaryMiddle.Val, RHS.Val);
}
}
@ -446,10 +453,24 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
return ParsePostfixExpressionSuffix(Res);
// primary-expression
case tok::numeric_constant:
// constant: integer-constant
// constant: floating-constant
// TODO: Validate whether this is an integer or floating-constant or
// neither.
if (1) {
Res = Actions.ParseIntegerConstant(Tok);
} else {
Res = Actions.ParseFloatingConstant(Tok);
}
ConsumeToken();
// These can be followed by postfix-expr pieces.
return ParsePostfixExpressionSuffix(Res);
case tok::identifier: // primary-expression: identifier
// constant: enumeration-constant
case tok::numeric_constant: // constant: integer-constant
// constant: floating-constant
case tok::char_constant: // constant: character-constant
case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]

View File

@ -19,15 +19,15 @@ using namespace clang;
/// Interface to the Builder.cpp file.
///
Action *CreateASTBuilderActions();
Action *CreateASTBuilderActions(bool FullLocInfo);
namespace {
class ASTStreamer {
Parser P;
public:
ASTStreamer(Preprocessor &PP, unsigned MainFileID)
: P(PP, *CreateASTBuilderActions()) {
ASTStreamer(Preprocessor &PP, unsigned MainFileID, bool FullLocInfo)
: P(PP, *CreateASTBuilderActions(FullLocInfo)) {
PP.EnterSourceFile(MainFileID, 0, true);
// Initialize the parser.
@ -59,8 +59,9 @@ namespace {
/// ASTStreamer_Init - Create an ASTStreamer with the specified preprocessor
/// and FileID.
ASTStreamerTy *llvm::clang::ASTStreamer_Init(Preprocessor &PP,
unsigned MainFileID) {
return new ASTStreamer(PP, MainFileID);
unsigned MainFileID,
bool FullLocInfo) {
return new ASTStreamer(PP, MainFileID, FullLocInfo);
}
/// ASTStreamer_ReadTopLevelDecl - Parse and return one top-level declaration. This

View File

@ -13,9 +13,11 @@
//===----------------------------------------------------------------------===//
#include "clang/Parse/Action.h"
#include "clang/Parse/Scope.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Parse/Scope.h"
#include "clang/Lex/IdentifierTable.h"
#include "clang/Lex/LexerToken.h"
#include "llvm/Support/Visibility.h"
using namespace llvm;
using namespace clang;
@ -23,7 +25,11 @@ using namespace clang;
/// ASTBuilder
namespace {
class VISIBILITY_HIDDEN ASTBuilder : public Action {
/// FullLocInfo - If this is true, the ASTBuilder constructs AST Nodes that
/// capture maximal location information for each source-language construct.
bool FullLocInfo;
public:
ASTBuilder(bool fullLocInfo) : FullLocInfo(fullLocInfo) {}
//===--------------------------------------------------------------------===//
// Symbol table tracking callbacks.
//
@ -31,6 +37,20 @@ public:
virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
ExprTy *Init);
virtual void PopScope(SourceLocation Loc, Scope *S);
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks.
virtual ExprTy *ParseIntegerConstant(const LexerToken &Tok);
virtual ExprTy *ParseFloatingConstant(const LexerToken &Tok);
// Binary Operators. 'Tok' is the token
virtual ExprTy *ParseBinOp(const LexerToken &Tok, ExprTy *LHS, ExprTy *RHS);
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
/// in the case of a the GNU conditional expr extension.
virtual ExprTy *ParseConditionalOp(SourceLocation QuestionLoc,
SourceLocation ColonLoc,
ExprTy *Cond, ExprTy *LHS, ExprTy *RHS);
};
} // end anonymous namespace
@ -75,11 +95,79 @@ void ASTBuilder::PopScope(SourceLocation Loc, Scope *S) {
}
}
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks.
//===--------------------------------------------------------------------===//
ASTBuilder::ExprTy *ASTBuilder::ParseIntegerConstant(const LexerToken &Tok) {
return new IntegerConstant();
}
ASTBuilder::ExprTy *ASTBuilder::ParseFloatingConstant(const LexerToken &Tok) {
return new FloatingConstant();
}
// Binary Operators. 'Tok' is the token for the operator.
ASTBuilder::ExprTy *ASTBuilder::ParseBinOp(const LexerToken &Tok, ExprTy *LHS,
ExprTy *RHS) {
BinaryOperator::Opcode Opc;
switch (Tok.getKind()) {
default: assert(0 && "Unknown binop!");
case tok::star: Opc = BinaryOperator::Mul; break;
case tok::slash: Opc = BinaryOperator::Div; break;
case tok::percent: Opc = BinaryOperator::Rem; break;
case tok::plus: Opc = BinaryOperator::Add; break;
case tok::minus: Opc = BinaryOperator::Sub; break;
case tok::lessless: Opc = BinaryOperator::Shl; break;
case tok::greatergreater: Opc = BinaryOperator::Shr; break;
case tok::lessequal: Opc = BinaryOperator::LE; break;
case tok::less: Opc = BinaryOperator::LT; break;
case tok::greaterequal: Opc = BinaryOperator::GE; break;
case tok::greater: Opc = BinaryOperator::GT; break;
case tok::exclaimequal: Opc = BinaryOperator::NE; break;
case tok::equalequal: Opc = BinaryOperator::EQ; break;
case tok::amp: Opc = BinaryOperator::And; break;
case tok::caret: Opc = BinaryOperator::Xor; break;
case tok::pipe: Opc = BinaryOperator::Or; break;
case tok::ampamp: Opc = BinaryOperator::LAnd; break;
case tok::pipepipe: Opc = BinaryOperator::LOr; break;
case tok::equal: Opc = BinaryOperator::Assign; break;
case tok::starequal: Opc = BinaryOperator::MulAssign; break;
case tok::slashequal: Opc = BinaryOperator::DivAssign; break;
case tok::percentequal: Opc = BinaryOperator::RemAssign; break;
case tok::plusequal: Opc = BinaryOperator::AddAssign; break;
case tok::minusequal: Opc = BinaryOperator::SubAssign; break;
case tok::lesslessequal: Opc = BinaryOperator::ShlAssign; break;
case tok::greatergreaterequal: Opc = BinaryOperator::ShrAssign; break;
case tok::ampequal: Opc = BinaryOperator::AndAssign; break;
case tok::caretequal: Opc = BinaryOperator::XorAssign; break;
case tok::pipeequal: Opc = BinaryOperator::OrAssign; break;
case tok::comma: Opc = BinaryOperator::Comma; break;
}
if (!FullLocInfo)
return new BinaryOperator((Expr*)LHS, (Expr*)RHS, Opc);
else
return new BinaryOperatorLOC((Expr*)LHS, Tok.getLocation(), (Expr*)RHS,Opc);
}
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
/// in the case of a the GNU conditional expr extension.
ASTBuilder::ExprTy *ASTBuilder::ParseConditionalOp(SourceLocation QuestionLoc,
SourceLocation ColonLoc,
ExprTy *Cond, ExprTy *LHS,
ExprTy *RHS) {
if (!FullLocInfo)
return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
else
return new ConditionalOperatorLOC((Expr*)Cond, QuestionLoc, (Expr*)LHS,
ColonLoc, (Expr*)RHS);
}
/// Interface to the Builder.cpp file.
///
Action *CreateASTBuilderActions() {
return new ASTBuilder();
Action *CreateASTBuilderActions(bool FullLocInfo) {
return new ASTBuilder(FullLocInfo);
}

View File

@ -18,6 +18,7 @@
DE06E4D70A8FBF7A0050E87E /* Initializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE06E4D60A8FBF7A0050E87E /* Initializer.cpp */; };
DE06E8140A8FF9330050E87E /* Action.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06E8130A8FF9330050E87E /* Action.h */; };
DE0FCA210A95710600248FD5 /* EmptyAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE0FCA200A95710600248FD5 /* EmptyAction.cpp */; };
DE0FCA630A95859D00248FD5 /* Expr.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE0FCA620A95859D00248FD5 /* Expr.h */; };
DE1F22030A7D852A00FBF588 /* Parser.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F22020A7D852A00FBF588 /* Parser.h */; };
DE1F24820A7DCD3800FBF588 /* Declarations.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F24810A7DCD3800FBF588 /* Declarations.h */; };
DEAEE98B0A5A2B970045101B /* MultipleIncludeOpt.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */; };
@ -98,13 +99,14 @@
DEC8D9910A9433CD00353FCA /* Decl.h in CopyFiles */,
DEC8D9A40A94346E00353FCA /* AST.h in CopyFiles */,
DEC8DAC00A94402500353FCA /* ASTStreamer.h in CopyFiles */,
DE0FCA630A95859D00248FD5 /* Expr.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };
DE06BEC80A854E390050E87E /* Scope.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Scope.cpp; path = Parse/Scope.cpp; sourceTree = "<group>"; };
DE06BECA0A854E4B0050E87E /* Scope.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Scope.h; path = clang/Parse/Scope.h; sourceTree = "<group>"; };
@ -116,6 +118,7 @@
DE06E4D60A8FBF7A0050E87E /* Initializer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Initializer.cpp; path = Parse/Initializer.cpp; sourceTree = "<group>"; };
DE06E8130A8FF9330050E87E /* Action.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Action.h; path = clang/Parse/Action.h; sourceTree = "<group>"; };
DE0FCA200A95710600248FD5 /* EmptyAction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = EmptyAction.cpp; path = Parse/EmptyAction.cpp; sourceTree = "<group>"; };
DE0FCA620A95859D00248FD5 /* Expr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Expr.h; path = clang/AST/Expr.h; sourceTree = "<group>"; };
DE1F22020A7D852A00FBF588 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = clang/Parse/Parser.h; sourceTree = "<group>"; };
DE1F24810A7DCD3800FBF588 /* Declarations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Declarations.h; path = clang/Parse/Declarations.h; sourceTree = "<group>"; };
DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MultipleIncludeOpt.h; sourceTree = "<group>"; };
@ -255,6 +258,7 @@
DEC8D9A30A94346E00353FCA /* AST.h */,
DEC8DABF0A94402500353FCA /* ASTStreamer.h */,
DEC8D9900A9433CD00353FCA /* Decl.h */,
DE0FCA620A95859D00248FD5 /* Expr.h */,
);
name = AST;
sourceTree = "<group>";

View File

@ -24,11 +24,14 @@ namespace clang {
typedef void ASTStreamerTy;
/// ASTStreamer_Init - Create an ASTStreamer with the specified preprocessor
/// and FileID.
ASTStreamerTy *ASTStreamer_Init(Preprocessor &PP, unsigned MainFileID);
/// and FileID. If FullLocInfo is true, full location information is captured
/// in the AST nodes. This takes more space, but allows for very accurate
/// position reporting.
ASTStreamerTy *ASTStreamer_Init(Preprocessor &PP, unsigned MainFileID,
bool FullLocInfo = false);
/// ASTStreamer_ReadTopLevelDecl - Parse and return one top-level declaration. This
/// returns null at end of file.
/// ASTStreamer_ReadTopLevelDecl - Parse and return one top-level declaration.
/// This returns null at end of file.
Decl *ASTStreamer_ReadTopLevelDecl(ASTStreamerTy *Streamer);
/// ASTStreamer_Terminate - Gracefully shut down the streamer.

View File

@ -0,0 +1,104 @@
//===--- Expr.h - Classes for representing expressions ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the Expr interface and subclasses.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_EXPR_H
#define LLVM_CLANG_AST_EXPR_H
#include "clang/Basic/SourceLocation.h"
namespace llvm {
namespace clang {
/// Expr - This represents one expression etc.
///
class Expr {
/// Type.
public:
Expr() {}
virtual ~Expr() {}
};
class IntegerConstant : public Expr {
public:
IntegerConstant() {}
};
class FloatingConstant : public Expr {
public:
FloatingConstant() {}
};
class BinaryOperator : public Expr {
public:
enum Opcode {
// Operators listed in order of precedence.
Mul, Div, Rem, // [C99 6.5.5] Multiplicative operators.
Add, Sub, // [C99 6.5.6] Additive operators.
Shl, Shr, // [C99 6.5.7] Bitwise shift operators.
LT, GT, LE, GE, // [C99 6.5.8] Relational operators.
EQ, NE, // [C99 6.5.9] Equality operators.
And, // [C99 6.5.10] Bitwise AND operator.
Xor, // [C99 6.5.11] Bitwise XOR operator.
Or, // [C99 6.5.12] Bitwise OR operator.
LAnd, // [C99 6.5.13] Logical AND operator.
LOr, // [C99 6.5.14] Logical OR operator.
Assign, MulAssign,// [C99 6.5.16] Assignment operators.
DivAssign, RemAssign,
AddAssign, SubAssign,
ShlAssign, ShrAssign,
AndAssign, XorAssign,
OrAssign,
Comma // [C99 6.5.17] Comma operator.
};
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc)
: LHS(lhs), RHS(rhs), Opc(opc) {}
private:
Expr *LHS, *RHS;
Opcode Opc;
};
class BinaryOperatorLOC : public BinaryOperator {
SourceLocation OperatorLoc;
public:
BinaryOperatorLOC(Expr *LHS, SourceLocation OpLoc, Expr *RHS, Opcode Opc)
: BinaryOperator(LHS, RHS, Opc), OperatorLoc(OpLoc) {
}
};
/// ConditionalOperator - The ?: operator. Note that LHS may be null when the
/// GNU "missing LHS" extension is in use.
///
class ConditionalOperator : public Expr {
Expr *Cond, *LHS, *RHS; // Left/Middle/Right hand sides.
public:
ConditionalOperator(Expr *cond, Expr *lhs, Expr *rhs)
: Cond(cond), LHS(lhs), RHS(rhs) {}
};
/// ConditionalOperatorLOC - ConditionalOperator with full location info.
///
class ConditionalOperatorLOC : public ConditionalOperator {
SourceLocation QuestionLoc, ColonLoc;
public:
ConditionalOperatorLOC(Expr *Cond, SourceLocation QLoc, Expr *LHS,
SourceLocation CLoc, Expr *RHS)
: ConditionalOperator(Cond, LHS, RHS), QuestionLoc(QLoc), ColonLoc(CLoc) {}
};
} // end namespace clang
} // end namespace llvm
#endif

View File

@ -25,6 +25,7 @@ namespace clang {
class Action;
// Lex.
class IdentifierInfo;
class LexerToken;
/// Action - As the parser reads the input file and recognizes the productions
/// of the grammar, it invokes methods on this class to turn the parsed input
@ -48,7 +49,7 @@ public:
typedef void DeclTy;
//===--------------------------------------------------------------------===//
// Symbol table tracking callbacks.
// Symbol Table Tracking Callbacks.
//===--------------------------------------------------------------------===//
/// isTypedefName - Return true if the specified identifier is a typedef name
@ -65,6 +66,26 @@ public:
/// is popped and deleted.
virtual void PopScope(SourceLocation Loc, Scope *S) {}
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks.
//===--------------------------------------------------------------------===//
// Primary Expressions.
virtual ExprTy *ParseIntegerConstant(const LexerToken &Tok) { return 0; }
virtual ExprTy *ParseFloatingConstant(const LexerToken &Tok) { return 0; }
// Binary Operators. 'Tok' is the token
virtual ExprTy *ParseBinOp(const LexerToken &Tok, ExprTy *LHS, ExprTy *RHS) {
return 0;
}
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
/// in the case of a the GNU conditional expr extension.
virtual ExprTy *ParseConditionalOp(SourceLocation QuestionLoc,
SourceLocation ColonLoc,
ExprTy *Cond, ExprTy *LHS, ExprTy *RHS) {
return 0;
}
};

View File

@ -225,6 +225,12 @@ private:
bool isInvalid;
ExprResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {}
const ExprResult &operator=(ExprTy *RHS) {
Val = RHS;
isInvalid = false;
return *this;
}
};
ExprResult ParseExpression();

View File

@ -24,11 +24,14 @@ namespace clang {
typedef void ASTStreamerTy;
/// ASTStreamer_Init - Create an ASTStreamer with the specified preprocessor
/// and FileID.
ASTStreamerTy *ASTStreamer_Init(Preprocessor &PP, unsigned MainFileID);
/// and FileID. If FullLocInfo is true, full location information is captured
/// in the AST nodes. This takes more space, but allows for very accurate
/// position reporting.
ASTStreamerTy *ASTStreamer_Init(Preprocessor &PP, unsigned MainFileID,
bool FullLocInfo = false);
/// ASTStreamer_ReadTopLevelDecl - Parse and return one top-level declaration. This
/// returns null at end of file.
/// ASTStreamer_ReadTopLevelDecl - Parse and return one top-level declaration.
/// This returns null at end of file.
Decl *ASTStreamer_ReadTopLevelDecl(ASTStreamerTy *Streamer);
/// ASTStreamer_Terminate - Gracefully shut down the streamer.