用C/C++做开发时,有很多的宏命令,绕来绕去的,很难看清楚关系。一般的编译器都提供了展开的命令,VC下的命令如下:
CL /EP /C YourCodeFile.cpp
This command will carry out all preprocessor directives and expand macros in the C++ code file "YourCodeFile.cpp". The/EP option suppresses compilation. /EP also suppresses the output files from the /FA, /Fa, and /Fm options. The/C (Preserve Comments During Preprocessing) option is used to preserve comments in the preprocessed output.
这个是从msdn上摘下来的,除了可以用于cpp文件之外,还可以用于.h头文件。
我将v8的ast.h展开后可以看见他的astNode类的定义:
class AstNode: public ZoneObject {
public:
#define DECLARE_TYPE_ENUM(type) k##type,
enum Type {
AST_NODE_LIST(DECLARE_TYPE_ENUM)
kInvalid = -1
};
#undef DECLARE_TYPE_ENUM
.....
virtual void Accept(AstVisitor* v) = 0;
virtual Type node_type() const = 0;
// Type testing & conversion functions overridden by concrete subclasses.
#define DECLARE_NODE_FUNCTIONS(type) \
bool Is##type() { return node_type() == AstNode::k##type; } \
type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
#undef DECLARE_NODE_FUNCTIONS
...
}
将无关的代码略掉了。展开后的结果如下:
class AstNode: public ZoneObject {
public:
enum Type {
kVariableDeclaration, kFunctionDeclaration, kModuleDeclaration, kImportDeclaration, kExportDeclaration, kModuleLiteral, kModuleVariable, kModulePath,
kModuleUrl, kBlock, kExpressionStatement, kEmptyStatement, kIfStatement, kContinueStatement, kBreakStatement, kReturnStatement, kWithStatement,
kSwitchStatement, kDoWhileStatement, kWhileStatement, kForStatement, kForInStatement, kTryCatchStatement, kTryFinallyStatement, kDebuggerStatement,
kFunctionLiteral, kSharedFunctionInfoLiteral, kConditional, kVariableProxy, kLiteral, kRegExpLiteral, kObjectLiteral, kArrayLiteral, kAssignment,
kThrow, kProperty, kCall, kCallNew, kCallRuntime, kUnaryOperation, kCountOperation, kBinaryOperation, kCompareOperation, kThisFunction,
kInvalid = -1
};
virtual void Accept(AstVisitor* v) = 0;
virtual Type node_type() const = 0;
// Type testing & conversion functions overridden by concrete subclasses.
bool IsVariableDeclaration() { return node_type() == AstNode::kVariableDeclaration; }
VariableDeclaration* AsVariableDeclaration() { return IsVariableDeclaration() ? reinterpret_cast<VariableDeclaration*>(this) : NULL; }
bool IsFunctionDeclaration() { return node_type() == AstNode::kFunctionDeclaration; }
FunctionDeclaration* AsFunctionDeclaration() { return IsFunctionDeclaration() ? reinterpret_cast<FunctionDeclaration*>(this) : NULL; }
bool IsModuleDeclaration() { return node_type() == AstNode::kModuleDeclaration; }
ModuleDeclaration* AsModuleDeclaration() { return IsModuleDeclaration() ? reinterpret_cast<ModuleDeclaration*>(this) : NULL; }
.......
一目了然,很好看懂了类的结构了吧...