void CodeGenFunction::EmitDecl(const Decl &D) { switch (D.getKind()) { default: CGM.ErrorUnsupported(&D, "decl"); return; case Decl::ParmVar: assert(0 && "Parmdecls should not be in declstmts!"); case Decl::Function: // void X(); case Decl::Record: // struct/union/class X; case Decl::Enum: // enum X; case Decl::EnumConstant: // enum ? { X = ? } case Decl::CXXRecord: // struct/union/class X; [C++] case Decl::Using: // using X; [C++] case Decl::UsingShadow: case Decl::UsingDirective: // using namespace X; [C++] case Decl::StaticAssert: // static_assert(X, ""); [C++0x] // None of these decls require codegen support. return; case Decl::Var: { const VarDecl &VD = cast<VarDecl>(D); assert(VD.isBlockVarDecl() && "Should not see file-scope variables inside a function!"); return EmitBlockVarDecl(VD); } case Decl::Typedef: { // typedef int X; const TypedefDecl &TD = cast<TypedefDecl>(D); QualType Ty = TD.getUnderlyingType(); if (Ty->isVariablyModifiedType()) EmitVLASize(Ty); } } }
llvm::Value* CodeGenFunction::EmitIdentifierExpr(const IdentifierExpr* E) { Decl* D = E->getDecl(); if (!D) E->dump(); assert(D); switch (D->getKind()) { case DECL_FUNC: case DECL_VAR: break; case DECL_ENUMVALUE: { EnumConstantDecl* ECD = cast<EnumConstantDecl>(D); // Nasty, we need the value of the constant, but we have no place to store it. // We need to change the AST structure for this. // TODO correct width + value int value = 5; return llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), value, true); } case DECL_TYPE: case DECL_STRUCTTYPE: case DECL_FUNCTIONTYPE: case DECL_ARRAYVALUE: case DECL_USE: break; } assert(0 && "TODO?"); return 0; }
ASTNodeKind ASTNodeKind::getFromNode(const Decl &D) { switch (D.getKind()) { #define DECL(DERIVED, BASE) \ case Decl::DERIVED: return ASTNodeKind(NKI_##DERIVED##Decl); #define ABSTRACT_DECL(D) #include "clang/AST/DeclNodes.inc" }; llvm_unreachable("invalid decl kind"); }