Beispiel #1
0
    bool TraverseFunctionDecl(FunctionDecl *f) {
        // Function name
        DeclarationName DeclName = f->getNameInfo().getName();
        std::string FuncName = DeclName.getAsString();
        const FunctionType * fntyp = f->getType()->getAs<FunctionType>();

        if(!fntyp)
            return true;

        if(f->getStorageClass() == clang::SC_Static) {
            ImportError("cannot import static functions.");
            SetErrorReport(FuncName.c_str());
            return true;
        }

        Obj typ;
        if(!GetFuncType(fntyp,&typ)) {
            SetErrorReport(FuncName.c_str());
            return true;
        }
        std::string InternalName = FuncName;
        AsmLabelAttr * asmlabel = f->getAttr<AsmLabelAttr>();
        if(asmlabel) {
            InternalName = asmlabel->getLabel();
#ifndef __linux__
            //In OSX and Windows LLVM mangles assembler labels by adding a '\01' prefix
            InternalName.insert(InternalName.begin(), '\01');
#endif
        }
        CreateFunction(FuncName,InternalName,&typ);

        KeepFunctionLive(f);//make sure this function is live in codegen by creating a dummy reference to it (void) is to suppress unused warnings

        return true;
    }
Beispiel #2
0
 bool GetFuncType(const FunctionType * f, Obj * typ) {
     Obj returntype,parameters;
     resulttable->newlist(&parameters);
     
     bool valid = true; //decisions about whether this function can be exported or not are delayed until we have seen all the potential problems
 #if LLVM_VERSION <= 34
     QualType RT = f->getResultType();
 #else
     QualType RT = f->getReturnType();
 #endif
     if(RT->isVoidType()) {
         PushTypeField("unit");
         returntype.initFromStack(L, ref_table);
     } else {
         if(!GetType(RT,&returntype))
             valid = false;
     }
    
     
     const FunctionProtoType * proto = f->getAs<FunctionProtoType>();
     //proto is null if the function was declared without an argument list (e.g. void foo() and not void foo(void))
     //we don't support old-style C parameter lists, we just treat them as empty
     if(proto) {
     #if LLVM_VERSION >= 35
         for(size_t i = 0; i < proto->getNumParams(); i++) {
             QualType PT = proto->getParamType(i);
     #else
         for(size_t i = 0; i < proto->getNumArgs(); i++) {
             QualType PT = proto->getArgType(i);
     #endif
             Obj pt;
             if(!GetType(PT,&pt)) {
                 valid = false; //keep going with attempting to parse type to make sure we see all the reasons why we cannot support this function
             } else if(valid) {
                 pt.push();
                 parameters.addentry();
             }
         }
     }
     
     if(valid) {
         PushTypeField("functype");
         parameters.push();
         returntype.push();
         lua_pushboolean(L, proto ? proto->isVariadic() : false);
         lua_call(L, 3, 1);
         typ->initFromStack(L,ref_table);
     }
     
     return valid;
 }
 bool TraverseFunctionDecl(FunctionDecl *f) {
      // Function name
     DeclarationName DeclName = f->getNameInfo().getName();
     std::string FuncName = DeclName.getAsString();
     const FunctionType * fntyp = f->getType()->getAs<FunctionType>();
     
     if(!fntyp)
         return true;
     
     if(f->getStorageClass() == clang::SC_Static) {
         ImportError("cannot import static functions.");
         SetErrorReport(FuncName.c_str());
         return true;
     }
     
     Obj typ;
     if(!GetFuncType(fntyp,&typ)) {
         SetErrorReport(FuncName.c_str());
         return true;
     }
     std::string InternalName = FuncName;
     AsmLabelAttr * asmlabel = f->getAttr<AsmLabelAttr>();
     if(asmlabel) {
         InternalName = asmlabel->getLabel();
         #ifndef __linux__
             //In OSX and Windows LLVM mangles assembler labels by adding a '\01' prefix
             InternalName.insert(InternalName.begin(), '\01');
         #endif
     }
     CreateFunction(FuncName,InternalName,&typ);
     
     KeepFunctionLive(f);//make sure this function is live in codegen by creating a dummy reference to it (void) is to suppress unused warnings
     
     return true;
 }