diff options
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 115 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 37 | ||||
| -rw-r--r-- | clang/lib/CodeGen/ModuleBuilder.cpp | 60 | 
3 files changed, 112 insertions, 100 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 3340cdff56a..99390c1135c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -86,10 +86,10 @@ void CodeGenModule::WarnUnsupported(const Decl *D, const char *Type) {                      &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 @@ void CodeGenModule::SetGlobalValueAttributes(const FunctionDecl *FD,      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 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,    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 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {    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::GetAddrOfConstantString(const std::string &str) {  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"); +  } +} +   diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index dd8ac1739f9..5f3714cb283 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -52,8 +52,8 @@ namespace CodeGen {    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 @@ public:    /// 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 @@ public:    /// 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 @@ public:    /// 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 @@ public:                                     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 @@ private:    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); diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 17ac0023f8d..dafc0f5e258 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -63,63 +63,15 @@ namespace {      }      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  | 

