Mercurial > projects > ldc
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 */