OS << Node->getDecl()->getName();
}
+void StmtPrinter::VisitPreDefinedExpr(PreDefinedExpr *Node) {
+ switch (Node->getIdentType()) {
+ default:
+ assert(0 && "unknown case");
+ case PreDefinedExpr::Func:
+ OS << "__func__";
+ break;
+ case PreDefinedExpr::Function:
+ OS << "__FUNCTION__";
+ break;
+ case PreDefinedExpr::PrettyFunction:
+ OS << "__PRETTY_FUNCTION__";
+ break;
+ }
+}
+
void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
// FIXME should print an L for wchar_t constants
unsigned value = Node->getValue();
case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
+ case Expr::PreDefinedExprClass:
+ return EmitPreDefinedLValue(cast<PreDefinedExpr>(E));
case Expr::StringLiteralClass:
return EmitStringLiteralLValue(cast<StringLiteral>(E));
return LValue::MakeAddr(C);
}
+LValue CodeGenFunction::EmitPreDefinedLValue(const PreDefinedExpr *E) {
+ std::string FunctionName(CurFuncDecl->getName());
+ std::string GlobalVarName;
+
+ switch (E->getIdentType()) {
+ default:
+ assert(0 && "unknown pre-defined ident type");
+ case PreDefinedExpr::Func:
+ GlobalVarName = "__func__.";
+ break;
+ case PreDefinedExpr::Function:
+ GlobalVarName = "__FUNCTION__.";
+ break;
+ case PreDefinedExpr::PrettyFunction:
+ // FIXME:: Demangle C++ method names
+ GlobalVarName = "__PRETTY_FUNCTION__.";
+ break;
+ }
+
+ GlobalVarName += CurFuncDecl->getName();
+
+ // FIXME: Can cache/reuse these within the module.
+ llvm::Constant *C=llvm::ConstantArray::get(FunctionName);
+
+ // Create a global variable for this.
+ C = new llvm::GlobalVariable(C->getType(), true,
+ llvm::GlobalValue::InternalLinkage,
+ C, GlobalVarName, CurFn->getParent());
+ llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
+ llvm::Constant *Zeros[] = { Zero, Zero };
+ C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
+ return LValue::MakeAddr(C);
+}
+
LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
// The index must always be a pointer or integer, neither of which is an
// aggregate. Emit it.
return EmitLoadOfLValue(E);
case Expr::ArraySubscriptExprClass:
return EmitArraySubscriptExprRV(cast<ArraySubscriptExpr>(E));
+ case Expr::PreDefinedExprClass:
case Expr::StringLiteralClass:
return RValue::get(EmitLValue(E).getAddress());
class CompoundAssignOperator;
class ArraySubscriptExpr;
class ConditionalOperator;
+ class PreDefinedExpr;
class BlockVarDecl;
class EnumConstantDecl;
LValue EmitDeclRefLValue(const DeclRefExpr *E);
LValue EmitStringLiteralLValue(const StringLiteral *E);
+ LValue EmitPreDefinedLValue(const PreDefinedExpr *E);
LValue EmitUnaryOpLValue(const UnaryOperator *E);
LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E);
case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
- Res = Actions.ParseSimplePrimaryExpr(Tok.getLocation(), SavedKind);
+ Res = Actions.ParsePreDefinedExpr(Tok.getLocation(), SavedKind);
ConsumeToken();
// These can be followed by postfix-expr pieces.
return ParsePostfixExpressionSuffix(Res);
virtual ExprResult ParseIdentifierExpr(Scope *S, SourceLocation Loc,
IdentifierInfo &II,
bool HasTrailingLParen);
- virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
+ virtual ExprResult ParsePreDefinedExpr(SourceLocation Loc,
tok::TokenKind Kind);
virtual ExprResult ParseNumericConstant(const Token &);
virtual ExprResult ParseCharacterConstant(const Token &);
abort();
}
-Sema::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc,
- tok::TokenKind Kind) {
+Sema::ExprResult Sema::ParsePreDefinedExpr(SourceLocation Loc,
+ tok::TokenKind Kind) {
+ PreDefinedExpr::IdentType IT;
+
switch (Kind) {
default:
assert(0 && "Unknown simple primary expr!");
- // TODO: MOVE this to be some other callback.
case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
+ IT = PreDefinedExpr::Func;
+ break;
case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
+ IT = PreDefinedExpr::Function;
+ break;
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
- return 0;
+ IT = PreDefinedExpr::PrettyFunction;
+ break;
}
+
+ // Pre-defined identifiers are always of type char *.
+ return new PreDefinedExpr(Loc, Context.getPointerType(Context.CharTy), IT);
}
Sema::ExprResult Sema::ParseCharacterConstant(const Token &Tok) {
static bool classof(const DeclRefExpr *) { return true; }
};
+// PreDefinedExpr - [C99 6.4.2.2] - A pre-defined identifier such as __func__
+class PreDefinedExpr : public Expr {
+public:
+ enum IdentType {
+ Func,
+ Function,
+ PrettyFunction
+ };
+
+private:
+ SourceLocation Loc;
+ IdentType Type;
+public:
+ PreDefinedExpr(SourceLocation l, QualType type, IdentType IT)
+ : Expr(PreDefinedExprClass, type), Loc(l), Type(IT) {}
+
+ IdentType getIdentType() const { return Type; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == PreDefinedExprClass;
+ }
+ static bool classof(const PreDefinedExpr *) { return true; }
+};
+
class IntegerLiteral : public Expr {
llvm::APInt Value;
SourceLocation Loc;
STMT(16, DeclStmt , Stmt)
LAST_STMT(16)
-FIRST_EXPR(32)
+FIRST_EXPR(31)
// Expressions.
-STMT(32, Expr , Stmt)
+STMT(31, Expr , Stmt)
+STMT(32, PreDefinedExpr , Expr)
STMT(33, DeclRefExpr , Expr)
STMT(34, IntegerLiteral , Expr)
STMT(35, FloatingLiteral , Expr)
return 0;
}
- virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
- tok::TokenKind Kind) {
+ virtual ExprResult ParsePreDefinedExpr(SourceLocation Loc,
+ tok::TokenKind Kind) {
return 0;
}
virtual ExprResult ParseCharacterConstant(const Token &) { return 0; }