view dmd2/module.h @ 1117:4c20fcc4252b

Fun with parameter attributes: For several of the "synthetic" parameters added to D functions, we can apply noalias and nocapture. They are sret parameters, 'nest' pointers passed to nested functions, and _argptr: Nocapture: - Sret and nest are nocapture because they don't represent D-level variables, and thus the callee can't (validly) obtain a pointer to them, let alone keep it around after it returns. - _argptr is nocapture because although the callee has access to it as a pointer, that pointer is invalidated when it returns. All three are noalias because they're function-local variables - Sret and _argptr are noalias because they're freshly alloca'd memory only used for a single function call that's not allowed to keep an aliasing pointer to it around (since the parameter is nocapture). - 'Nest' is noalias because the callee only ever has access to one such pointer per parent function, and every parent function has a different one. This commit also ensures attributes set on sret, _arguments and _argptr are propagated to calls to such functions. It also adds one exception to the general rule that attributes on function types should propagate to calls: the type of a delegate's function pointer has a 'nest' parameter, but this can either be a true 'nest' (for delegates to nested functions) or a 'this' (for delegates to member functions). Since 'this' is neither noalias nor nocapture, and there's generally no way to tell which one it is, we remove these attributes at the call site if the callee is a delegate.
author Frits van Bommel <fvbommel wxs.nl>
date Sat, 14 Mar 2009 22:15:31 +0100
parents 5f5e6eb790e7
children 638d16625da2
line wrap: on
line source


// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.

#ifndef DMD_MODULE_H
#define DMD_MODULE_H

#ifdef __DMC__
#pragma once
#endif /* __DMC__ */

#include "root.h"
#include "dsymbol.h"

struct ModuleInfoDeclaration;
struct ClassDeclaration;
struct ModuleDeclaration;
struct Macro;
struct Escape;
struct VarDeclaration;
struct Library;

// Back end
#if IN_LLVM
struct DValue;
typedef DValue elem;
#else
#ifdef IN_GCC
union tree_node; typedef union tree_node elem;
#else
struct elem;
#endif
#endif

struct Package : ScopeDsymbol
{
    Package(Identifier *ident);
    const char *kind();

    static DsymbolTable *resolve(Array *packages, Dsymbol **pparent, Package **ppkg);

    Package *isPackage() { return this; }

    virtual void semantic(Scope *sc) { }
};

struct Module : Package
{
    static Module *rootModule;
    static DsymbolTable *modules;	// symbol table of all modules
    static Array amodules;		// array of all modules
    static Array deferred;	// deferred Dsymbol's needing semantic() run on them
    static unsigned dprogress;	// progress resolving the deferred list
    static void init();

    static ClassDeclaration *moduleinfo;


    const char *arg;	// original argument name
    ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
    File *srcfile;	// input source file

    File *objfile; // output object file
    File *docfile; // output doc file
    File *hdrfile; // output hdr file
    
    unsigned errors;	// if any errors in file
    unsigned numlines;	// number of lines in source file
    int isHtml;		// if it is an HTML file
    int isDocFile;	// if it is a documentation input file, not D source
    int needmoduleinfo;
#ifdef IN_GCC
    int strictlyneedmoduleinfo;
#endif

    int insearch;
    Identifier *searchCacheIdent;
    Dsymbol *searchCacheSymbol;	// cached value of search
    int searchCacheFlags;	// cached flags

    int semanticstarted;	// has semantic() been started?
    int semanticdone;		// has semantic() been done?
    int root;			// != 0 if this is a 'root' module,
				// i.e. a module that will be taken all the
				// way to an object file
    Module *importedFrom;	// module from command line we're imported from,
				// i.e. a module that will be taken all the
				// way to an object file

    Array *decldefs;		// top level declarations for this Module

    Array aimports;		// all imported modules

    ModuleInfoDeclaration *vmoduleinfo;

    unsigned debuglevel;	// debug level
    Array *debugids;		// debug identifiers
    Array *debugidsNot;		// forward referenced debug identifiers

    unsigned versionlevel;	// version level
    Array *versionids;		// version identifiers
    Array *versionidsNot;	// forward referenced version identifiers

    Macro *macrotable;		// document comment macros
    struct Escape *escapetable;	// document comment escapes

    int doDocComment;		// enable generating doc comments for this module
    int doHdrGen;		// enable generating header file for this module

    bool safe;

    Module(char *arg, Identifier *ident, int doDocComment, int doHdrGen);
    ~Module();

    static Module *load(Loc loc, Array *packages, Identifier *ident);

    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
    const char *kind();
    void read(Loc loc);	// read file
#if IN_GCC
    void parse(bool dump_source = false);	// syntactic parse
#else
    void parse();	// syntactic parse
#endif
    void semantic(Scope* unused_sc = NULL);	// semantic analysis
    void semantic2(Scope* unused_sc = NULL);	// pass 2 semantic analysis
    void semantic3(Scope* unused_sc = NULL);	// pass 3 semantic analysis
    void inlineScan();	// scan for functions to inline
#ifdef _DH
    void genhdrfile();  // generate D import file
#endif
    void genobjfile(int multiobj);
//    void gensymfile();
    void gendocfile();
    int needModuleInfo();
    Dsymbol *search(Loc loc, Identifier *ident, int flags);
    void deleteObjFile();
    void addDeferredSemantic(Dsymbol *s);
    void runDeferredSemantic();

    // Back end

    int doppelganger;		// sub-module
    Symbol *cov;		// private uint[] __coverage;
    unsigned *covb;		// bit array of valid code line numbers

    Symbol *sictor;		// module order independent constructor
    Symbol *sctor;		// module constructor
    Symbol *sdtor;		// module destructor
    Symbol *stest;		// module unit test

    Symbol *sfilename;		// symbol for filename

    Symbol *massert;		// module assert function
    Symbol *toModuleAssert();	// get module assert function

    Symbol *marray;		// module array bounds function
    Symbol *toModuleArray();	// get module array bounds function


    static Symbol *gencritsec();
    elem *toEfilename();
    elem *toEmodulename();

    Symbol *toSymbol();
    void genmoduleinfo();

    // LDC
    void buildTargetFiles();
    File* buildFilePath(char* forcename, const char* path, const char* ext);
    Module *isModule() { return this; }
    
    bool llvmForceLogging;

    // array ops emitted in this module already
    StringTable arrayfuncs;
};


struct ModuleDeclaration
{
    Identifier *id;
    Array *packages;		// array of Identifier's representing packages
    bool safe;

    ModuleDeclaration(Array *packages, Identifier *id, bool safe);

    char *toChars();
};

#endif /* DMD_MODULE_H */