[cfe-commits] r54827 - in /cfe/trunk/lib/CodeGen: CodeGenModule.cpp CodeGenModule.h ModuleBuilder.cpp
Daniel Dunbar
daniel at zuster.org
Fri Aug 15 16:26:23 PDT 2008
Author: ddunbar
Date: Fri Aug 15 18:26:23 2008
New Revision: 54827
URL: http://llvm.org/viewvc/llvm-project?rev=54827&view=rev
Log:
Clean up CodeGenModule interface.
- Add CodeGenModule::EmitTopLevelDecl which uses switch on kind
instead of ugly & slow dyn_cast chains.
- Drop some simple forwarding methods into the ObjC runtime.
- Privatize appropriate methods.
Modified:
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=54827&r1=54826&r2=54827&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Aug 15 18:26:23 2008
@@ -86,10 +86,10 @@
&Msg, 1);
}
-/// setVisibility - Set the visibility for the given LLVM GlobalValue
-/// according to the given clang AST visibility value.
-void CodeGenModule::setVisibility(llvm::GlobalValue *GV,
- VisibilityAttr::VisibilityTypes Vis) {
+/// setGlobalVisibility - Set the visibility for the given LLVM
+/// GlobalValue according to the given clang AST visibility value.
+static void setGlobalVisibility(llvm::GlobalValue *GV,
+ VisibilityAttr::VisibilityTypes Vis) {
switch (Vis) {
default: assert(0 && "Unknown visibility!");
case VisibilityAttr::DefaultVisibility:
@@ -185,7 +185,7 @@
GV->setLinkage(llvm::Function::WeakLinkage);
if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>())
- CodeGenModule::setVisibility(GV, attr->getVisibility());
+ setGlobalVisibility(GV, attr->getVisibility());
// FIXME: else handle -fvisibility
if (const AsmLabelAttr *ALA = FD->getAttr<AsmLabelAttr>()) {
@@ -242,24 +242,6 @@
SetGlobalValueAttributes(FD, F);
}
-void CodeGenModule::EmitObjCMethod(const ObjCMethodDecl *OMD) {
- // If this is not a prototype, emit the body.
- if (OMD->getBody())
- CodeGenFunction(*this).GenerateObjCMethod(OMD);
-}
-void CodeGenModule::EmitObjCProtocolImplementation(const ObjCProtocolDecl *PD){
- Runtime->GenerateProtocol(PD);
-}
-
-void CodeGenModule::EmitObjCCategoryImpl(const ObjCCategoryImplDecl *OCD) {
- Runtime->GenerateCategory(OCD);
-}
-
-void
-CodeGenModule::EmitObjCClassImplementation(const ObjCImplementationDecl *OID) {
- Runtime->GenerateClass(OID);
-}
-
void CodeGenModule::EmitStatics() {
// Emit code for each used static decl encountered. Since a previously unused
// static decl may become used during the generation of code for a static
@@ -486,7 +468,7 @@
GV->setAlignment(Align / 8);
if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
- setVisibility(GV, attr->getVisibility());
+ setGlobalVisibility(GV, attr->getVisibility());
// FIXME: else handle -fvisibility
if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
@@ -849,3 +831,88 @@
llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &str) {
return GetAddrOfConstantString(str + "\0");
}
+
+/// EmitTopLevelDecl - Emit code for a single top level declaration.
+void CodeGenModule::EmitTopLevelDecl(Decl *D) {
+ // If an error has occurred, stop code generation, but continue
+ // parsing and semantic analysis (to ensure all warnings and errors
+ // are emitted).
+ if (Diags.hasErrorOccurred())
+ return;
+
+ switch (D->getKind()) {
+ case Decl::Function:
+ case Decl::Var:
+ EmitGlobal(cast<ValueDecl>(D));
+ break;
+
+ case Decl::Namespace:
+ assert(0 && "FIXME: Namespace unsupported");
+ break;
+
+ // Objective-C Decls
+
+ // Forward declarations, no (immediate) code generation.
+ case Decl::ObjCClass:
+ case Decl::ObjCCategory:
+ case Decl::ObjCForwardProtocol:
+ case Decl::ObjCInterface:
+ break;
+
+ case Decl::ObjCProtocol:
+ Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
+ break;
+
+ case Decl::ObjCCategoryImpl:
+ Runtime->GenerateCategory(cast<ObjCCategoryImplDecl>(D));
+ break;
+
+ case Decl::ObjCImplementation:
+ Runtime->GenerateClass(cast<ObjCImplementationDecl>(D));
+ break;
+
+ case Decl::ObjCMethod: {
+ ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D);
+ // If this is not a prototype, emit the body.
+ if (OMD->getBody())
+ CodeGenFunction(*this).GenerateObjCMethod(OMD);
+ break;
+ }
+ case Decl::ObjCPropertyImpl:
+ assert(0 && "FIXME: ObjCPropertyImpl unsupported");
+ break;
+ case Decl::ObjCCompatibleAlias:
+ assert(0 && "FIXME: ObjCCompatibleAlias unsupported");
+ break;
+
+ case Decl::LinkageSpec: {
+ LinkageSpecDecl *LSD = cast<LinkageSpecDecl>(D);
+ if (LSD->getLanguage() == LinkageSpecDecl::lang_cxx)
+ WarnUnsupported(LSD, "linkage spec");
+ // FIXME: implement C++ linkage, C linkage works mostly by C
+ // language reuse already.
+ break;
+ }
+
+ case Decl::FileScopeAsm: {
+ FileScopeAsmDecl *AD = cast<FileScopeAsmDecl>(D);
+ std::string AsmString(AD->getAsmString()->getStrData(),
+ AD->getAsmString()->getByteLength());
+
+ const std::string &S = getModule().getModuleInlineAsm();
+ if (S.empty())
+ getModule().setModuleInlineAsm(AsmString);
+ else
+ getModule().setModuleInlineAsm(S + '\n' + AsmString);
+ break;
+ }
+
+ default:
+ // Make sure we handled everything we should, every other kind is
+ // a non-top-level decl. FIXME: Would be nice to have an
+ // isTopLevelDeclKind function. Need to recode Decl::Kind to do
+ // that easily.
+ assert(isa<TypeDecl>(D) && "Unsupported decl kind");
+ }
+}
+
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=54827&r1=54826&r2=54827&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Aug 15 18:26:23 2008
@@ -52,8 +52,8 @@
class CGDebugInfo;
class CGObjCRuntime;
-/// CodeGenModule - This class organizes the cross-module state that is used
-/// while generating LLVM code.
+/// CodeGenModule - This class organizes the cross-function state that
+/// is used while generating LLVM code.
class CodeGenModule {
typedef std::vector< std::pair<llvm::Constant*, int> > CtorList;
@@ -138,11 +138,6 @@
/// GetAddrOfFunction - Return the llvm::Constant for the address
/// of the given function.
llvm::Constant *GetAddrOfFunction(const FunctionDecl *D);
-
- /// getBuiltinLibFunction - Given a builtin id for a function like
- /// "__builtin_fabsf", return a Function* for "fabsf".
- ///
- llvm::Function *getBuiltinLibFunction(unsigned BuiltinID);
/// GetStringForStringLiteral - Return the appropriate bytes for a
/// string literal, properly padded to match the literal type. If
@@ -150,6 +145,8 @@
/// GetAddrOfConstantStringLiteral.
std::string GetStringForStringLiteral(const StringLiteral *E);
+ /// GetAddrOfConstantCFString - Return a pointer to a
+ /// constant CFString object for the given string.
llvm::Constant *GetAddrOfConstantCFString(const std::string& str);
/// GetAddrOfConstantStringFromLiteral - Return a pointer to a
@@ -170,21 +167,19 @@
/// array containing the literal and a terminating '\-'
/// character. The result has pointer to array type.
llvm::Constant *GetAddrOfConstantCString(const std::string &str);
+
+ /// getBuiltinLibFunction - Given a builtin id for a function like
+ /// "__builtin_fabsf", return a Function* for "fabsf".
+ llvm::Function *getBuiltinLibFunction(unsigned BuiltinID);
llvm::Function *getMemCpyFn();
llvm::Function *getMemMoveFn();
llvm::Function *getMemSetFn();
llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0,
unsigned NumTys = 0);
-
- void EmitObjCMethod(const ObjCMethodDecl *OMD);
- void EmitObjCCategoryImpl(const ObjCCategoryImplDecl *OCD);
- void EmitObjCClassImplementation(const ObjCImplementationDecl *OID);
- void EmitObjCProtocolImplementation(const ObjCProtocolDecl *PD);
- /// EmitGlobal - Emit code for a singal global function or var
- /// decl. Forward declarations are emitted lazily.
- void EmitGlobal(const ValueDecl *D);
+ /// EmitTopLevelDecl - Emit code for a single top level declaration.
+ void EmitTopLevelDecl(Decl *D);
void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
@@ -194,18 +189,12 @@
const AnnotateAttr *AA, unsigned LineNo);
/// WarnUnsupported - Print out a warning that codegen doesn't support the
- /// specified stmt yet.
-
+ /// specified stmt yet.
void WarnUnsupported(const Stmt *S, const char *Type);
/// WarnUnsupported - Print out a warning that codegen doesn't support the
/// specified decl yet.
void WarnUnsupported(const Decl *D, const char *Type);
-
- /// setVisibility - Set the visibility for the given LLVM GlobalValue
- /// according to the given clang AST visibility value.
- static void setVisibility(llvm::GlobalValue *GV,
- VisibilityAttr::VisibilityTypes);
private:
void SetFunctionAttributes(const FunctionDecl *FD,
@@ -215,6 +204,10 @@
void SetGlobalValueAttributes(const FunctionDecl *FD,
llvm::GlobalValue *GV);
+ /// EmitGlobal - Emit code for a singal global function or var
+ /// decl. Forward declarations are emitted lazily.
+ void EmitGlobal(const ValueDecl *D);
+
void EmitGlobalDefinition(const ValueDecl *D);
llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D);
void EmitGlobalFunctionDefinition(const FunctionDecl *D);
Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=54827&r1=54826&r2=54827&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Fri Aug 15 18:26:23 2008
@@ -63,63 +63,15 @@
}
virtual void HandleTopLevelDecl(Decl *D) {
- // If an error occurred, stop code generation, but continue parsing and
- // semantic analysis (to ensure all warnings and errors are emitted).
- if (Diags.hasErrorOccurred())
- return;
-
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- Builder->EmitGlobal(FD);
- } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
- Builder->EmitGlobal(VD);
- } else if (isa<ObjCClassDecl>(D) || isa<ObjCForwardProtocolDecl>(D)) {
- //Forward declaration. Only used for type checking.
- } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)){
- // Generate Protocol object.
- Builder->EmitObjCProtocolImplementation(PD);
- } else if (isa<ObjCCategoryDecl>(D)){
- //Only used for typechecking.
- } else if (ObjCCategoryImplDecl *OCD = dyn_cast<ObjCCategoryImplDecl>(D)){
- // Generate methods, attach to category structure
- Builder->EmitObjCCategoryImpl(OCD);
- } else if (ObjCImplementationDecl * OID =
- dyn_cast<ObjCImplementationDecl>(D)){
- // Generate methods, attach to class structure
- Builder->EmitObjCClassImplementation(OID);
- } else if (isa<ObjCInterfaceDecl>(D)){
- // Ignore - generated when the implementation decl is CodeGen'd
- } else if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)){
- Builder->EmitObjCMethod(OMD);
- } else if (isa<ObjCClassDecl>(D) || isa<ObjCCategoryDecl>(D)) {
- // Forward declaration. Only used for type checking.
- } else if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)){
- Builder->EmitObjCMethod(OMD);
- } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
- if (LSD->getLanguage() == LinkageSpecDecl::lang_cxx)
- Builder->WarnUnsupported(LSD, "linkage spec");
- // FIXME: implement C++ linkage, C linkage works mostly by C
- // language reuse already.
- } else if (FileScopeAsmDecl *AD = dyn_cast<FileScopeAsmDecl>(D)) {
- std::string AsmString(AD->getAsmString()->getStrData(),
- AD->getAsmString()->getByteLength());
-
- const std::string &S = Builder->getModule().getModuleInlineAsm();
- if (S.empty())
- Builder->getModule().setModuleInlineAsm(AsmString);
- else
- Builder->getModule().setModuleInlineAsm(S + '\n' + AsmString);
- } else {
- assert(isa<TypeDecl>(D) && "Unknown top level decl");
- // TODO: handle debug info?
- }
-
+ // Make sure to emit all elements of a ScopedDecl.
if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
- SD = SD->getNextDeclarator();
- if (SD)
- HandleTopLevelDecl(SD);
+ for (; SD; SD = SD->getNextDeclarator())
+ Builder->EmitTopLevelDecl(SD);
+ } else {
+ Builder->EmitTopLevelDecl(D);
}
}
-
+
/// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
/// (e.g. struct, union, enum, class) is completed. This allows the client to
/// hack on the type, which can occur at any point in the file (because these
More information about the cfe-commits
mailing list