Import Clang, at r72805.

This commit is contained in:
ed 2009-06-03 21:11:25 +00:00
parent 48ecc7affe
commit 9e262ca77e
19 changed files with 1572 additions and 1035 deletions

View File

@ -33,6 +33,7 @@
1A471AB50F437BC500753CE8 /* CGBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A471AB40F437BC500753CE8 /* CGBlocks.cpp */; };
1A5119C40FBDF71000A1FF22 /* SemaTemplateInstantiateStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5119C30FBDF71000A1FF22 /* SemaTemplateInstantiateStmt.cpp */; };
1A5D5E580E5E81010023C059 /* CGCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5D5E570E5E81010023C059 /* CGCXX.cpp */; };
1A6FE7090FD6F85800E00CA9 /* CGCXXTemp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6FE7080FD6F85800E00CA9 /* CGCXXTemp.cpp */; };
1A701B640F7C8FE400FEC4D1 /* SemaAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A701B630F7C8FE400FEC4D1 /* SemaAccess.cpp */; };
1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7342470C7B57D500122F56 /* CGObjC.cpp */; };
1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
@ -352,6 +353,7 @@
1A68BC110D0CADDD001A28C8 /* PPCBuiltins.def */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = text; name = PPCBuiltins.def; path = clang/AST/PPCBuiltins.def; sourceTree = "<group>"; tabWidth = 2; };
1A68BC120D0CADDD001A28C8 /* TargetBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TargetBuiltins.h; path = clang/AST/TargetBuiltins.h; sourceTree = "<group>"; tabWidth = 2; };
1A68BC130D0CADDD001A28C8 /* X86Builtins.def */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = text; name = X86Builtins.def; path = clang/AST/X86Builtins.def; sourceTree = "<group>"; tabWidth = 2; };
1A6FE7080FD6F85800E00CA9 /* CGCXXTemp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGCXXTemp.cpp; path = lib/CodeGen/CGCXXTemp.cpp; sourceTree = "<group>"; };
1A7019E90F79BC1100FEC4D1 /* DiagnosticAnalysisKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticAnalysisKinds.td; sourceTree = "<group>"; };
1A7019EA0F79BC1100FEC4D1 /* DiagnosticASTKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticASTKinds.td; sourceTree = "<group>"; };
1A7019EB0F79BC1100FEC4D1 /* DiagnosticCommonKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticCommonKinds.td; sourceTree = "<group>"; };
@ -1093,6 +1095,7 @@
35475B220E7997680000BFE4 /* CGCall.h */,
1A5D5E570E5E81010023C059 /* CGCXX.cpp */,
1A649E1E0F9599DA005B965E /* CGCXX.h */,
1A6FE7080FD6F85800E00CA9 /* CGCXXTemp.cpp */,
35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */,
35A3E7010DD3874400757F74 /* CGDebugInfo.h */,
DE4264FB0C113592005A861D /* CGDecl.cpp */,
@ -1687,6 +1690,7 @@
1A2A54C30FD1DD1C00F4CE45 /* RewriteTest.cpp in Sources */,
1A2A54C40FD1DD1C00F4CE45 /* StmtXML.cpp in Sources */,
1A2A54C50FD1DD1C00F4CE45 /* Warnings.cpp in Sources */,
1A6FE7090FD6F85800E00CA9 /* CGCXXTemp.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -16,7 +16,26 @@
view, please see the <a
href="UsersManual.html#precompiledheaders">User's Manual</a>.</p>
<h2>Using precompiled headers with <tt>clang-cc</tt></h2>
<p><b>Table of Contents</b></p>
<ul>
<li><a href="#usage">Using Precompiled Headers with
<tt>clang-cc</tt></a></li>
<li><a href="#philosophy">Design Philosophy</a></li>
<li><a href="#contents">Precompiled Header Contents</a>
<ul>
<li><a href="#metadata">Metadata Block</a></li>
<li><a href="#sourcemgr">Source Manager Block</a></li>
<li><a href="#preprocessor">Preprocessor Block</a></li>
<li><a href="#types">Types Block</a></li>
<li><a href="#decls">Declarations Block</a></li>
<li><a href="#stmt">Statements and Expressions</a></li>
<li><a href="#idtable">Identifier Table Block</a></li>
<li><a href="#method-pool">Method Pool Block</a></li>
</ul>
</li>
</ul>
<h2 id="usage">Using Precompiled Headers with <tt>clang-cc</tt></h2>
<p>The low-level Clang compiler, <tt>clang-cc</tt>, supports two command
line options for generating and using PCH files.<p>
@ -36,7 +55,7 @@ with the <b><tt>-include-pch</tt></b> option:</p>
$ clang-cc -include-pch test.h.pch test.c -o test.s
</pre>
<h2>PCH Design Philosophy</h2>
<h2 id="philosophy">Design Philosophy</h2>
<p>Precompiled headers are meant to improve overall compile times for
projects, so the design of precompiled headers is entirely driven by
@ -86,7 +105,7 @@ for a translation unit is proportional to the amount of code actually
used from the header, rather than being proportional to the size of
the header itself.</p> </body>
<h2>Precompiled Header Contents</h2>
<h2 id="contents">Precompiled Header Contents</h2>
<img src="PCHLayout.png" align="right" alt="Precompiled header layout">
@ -98,13 +117,13 @@ either a block or a record within <a
format</a>. The contents of each of these logical blocks are described
below.</p>
<h3 name="metadata">Metadata Block</h3>
<h3 id="metadata">Metadata Block</h3>
<p>The metadata block contains several records that provide
information about how the precompiled header was built. This metadata
is primarily used to validate the use of a precompiled header. For
example, a precompiled header built for x86 (32-bit) cannot be used
when compiling for x86-64 (64-bit). The metadata block contains
example, a precompiled header built for a 32-bit x86 target cannot be used
when compiling for a 64-bit x86 target. The metadata block contains
information about:</p>
<dl>
@ -128,7 +147,7 @@ vice-versa).</dd>
<dt>Original file name</dt>
<dd>The full path of the header that was used to generate the
precompiled header.</dd> </dl>
precompiled header.</dd>
<dt>Predefines buffer</dt>
<dd>Although not explicitly stored as part of the metadata, the
@ -139,9 +158,11 @@ platform, and command-line options. For example, the predefines buffer
will contain "<code>#define __STDC__ 1</code>" when we are compiling C
without Microsoft extensions. The predefines buffer itself is stored
within the <a href="#sourcemgr">source manager block</a>, but its
contents are verified along with the rest of the metadata.</dd> </dl>
contents are verified along with the rest of the metadata.</dd>
<h3 name="sourcemgr">Source Manager Block</h3>
</dl>
<h3 id="sourcemgr">Source Manager Block</h3>
<p>The source manager block contains the serialized representation of
Clang's <a
@ -174,7 +195,7 @@ system calls performed when building the precompiled header. The
latter is particularly useful in reducing system time when searching
for include files.</p>
<h3 name="preprocessor">Preprocessor Block</h3>
<h3 id="preprocessor">Preprocessor Block</h3>
<p>The preprocessor block contains the serialized representation of
the preprocessor. Specifically, it contains all of the macros that
@ -185,7 +206,7 @@ name of the macro first occurs in the program. This lazy loading of
macro definitions is trigged by lookups into the <a
href="#idtable">identifier table</a>.</p>
<h3 name="types">Types Block</h3>
<h3 id="types">Types Block</h3>
<p>The types block contains the serialized representation of all of
the types referenced in the translation unit. Each Clang type node
@ -211,7 +232,7 @@ Clang's <a
href="http://clang.llvm.org/docs/InternalsManual.html#Type">QualType</a>
class.</p>
<h3 name="decls">Declarations Block</h3>
<h3 id="decls">Declarations Block</h3>
<p>The declarations block contains the serialized representation of
all of the declarations referenced in the translation unit. Each Clang
@ -274,7 +295,50 @@ the name-lookup and iteration behavior described above:</p>
contain relatively few declarations in the common case.</li>
</ul>
<h3 name="idtable">Identifier Table Block</h3>
<h3 id="stmt">Statements and Expressions</h3>
<p>Statements and expressions are stored in the precompiled header in
both the <a href="#types">types</a> and the <a
href="#decls">declarations</a> blocks, because every statement or
expression will be associated with either a type or declaration. The
actual statement and expression records are stored immediately
following the declaration or type that owns the statement or
expression. For example, the statement representing the body of a
function will be stored directly following the declaration of the
function.</p>
<p>As with types and declarations, each statement and expression kind
in Clang's abstract syntax tree (<code>ForStmt</code>,
<code>CallExpr</code>, etc.) has a corresponding record type in the
precompiled header, which contains the serialized representation of
that statement or expression. Each substatement or subexpression
within an expression is stored as a separate record (which keeps most
records to a fixed size). Within the precompiled header, the
subexpressions of an expression are stored prior to the expression
that owns those expression, using a form of <a
href="http://en.wikipedia.org/wiki/Reverse_Polish_notation">Reverse
Polish Notation</a>. For example, an expression <code>3 - 4 + 5</code>
would be represented as follows:</p>
<table border="1">
<tr><td><code>IntegerLiteral(3)</code></td></tr>
<tr><td><code>IntegerLiteral(4)</code></td></tr>
<tr><td><code>BinaryOperator(-)</code></td></tr>
<tr><td><code>IntegerLiteral(5)</code></td></tr>
<tr><td><code>BinaryOperator(+)</code></td></tr>
<tr><td>STOP</td></tr>
</table>
<p>When reading this representation, Clang evaluates each expression
record it encounters, builds the appropriate abstract synax tree node,
and then pushes that expression on to a stack. When a record contains <i>N</i>
subexpressions--<code>BinaryOperator</code> has two of them--those
expressions are popped from the top of the stack. The special STOP
code indicates that we have reached the end of a serialized expression
or statement; other expression or statement records may follow, but
they are part of a different expression.</p>
<h3 id="idtable">Identifier Table Block</h3>
<p>The identifier table block contains an on-disk hash table that maps
each identifier mentioned within the precompiled header to the
@ -299,14 +363,37 @@ contains:</p>
mechanism introduces itself into the identifier table as an external
lookup source. Thus, when the user program refers to an identifier
that has not yet been seen, Clang will perform a lookup into the
on-disk hash table ... FINISH THIS!
identifier table. If an identifier is found, its contents---macro definitions, flags, top-level declarations, etc.---will be deserialized, at which point the corresponding <code>IdentifierInfo</code> structure will have the same contents it would have after parsing the headers in the precompiled header.</p>
<p>A separate table provides a mapping from the numeric representation
of identifiers used in the PCH file to the location within the on-disk
<p>Within the PCH file, the identifiers used to name declarations are represented with an integral value. A separate table provides a mapping from this integral value (the identifier ID) to the location within the on-disk
hash table where that identifier is stored. This mapping is used when
deserializing the name of a declaration, the identifier of a token, or
any other construct in the PCH file that refers to a name.</p>
<h3 id="method-pool">Method Pool Block</h3>
<p>The method pool block is represented as an on-disk hash table that
serves two purposes: it provides a mapping from the names of
Objective-C selectors to the set of Objective-C instance and class
methods that have that particular selector (which is required for
semantic analysis in Objective-C) and also stores all of the selectors
used by entities within the precompiled header. The design of the
method pool is similar to that of the <a href="#idtable">identifier
table</a>: the first time a particular selector is formed during the
compilation of the program, Clang will search in the on-disk hash
table of selectors; if found, Clang will read the Objective-C methods
associated with that selector into the appropriate front-end data
structure (<code>Sema::InstanceMethodPool</code> and
<code>Sema::FactoryMethodPool</code> for instance and class methods,
respectively).</p>
<p>As with identifiers, selectors are represented by numeric values
within the PCH file. A separate index maps these numeric selector
values to the offset of the selector within the on-disk hash table,
and will be used when de-serializing an Objective-C method declaration
(or other Objective-C construct) that refers to the selector.</p>
<h2 id="tendrils"></h2>
</div>
</html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -28,10 +28,10 @@ namespace driver {
/// being run from. For testing purposes, the HostInfo used by the
/// driver may differ from the actual host.
class HostInfo {
protected:
const Driver &TheDriver;
const llvm::Triple Triple;
protected:
HostInfo(const Driver &D, const llvm::Triple &_Triple);
public:

View File

@ -493,6 +493,7 @@ OPTION("-mdynamic-no-pic", mdynamic_no_pic, Joined, m_Group, INVALID, "q", 0, 0,
OPTION("-mfix-and-continue", mfix_and_continue, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0)
OPTION("-miphoneos-version-min=", miphoneos_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mkernel", mkernel, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mllvm", mllvm, Separate, INVALID, INVALID, "", 0, 0, 0)
OPTION("-mmacosx-version-min=", mmacosx_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mmmx", mmmx, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-3dnowa", mno_3dnowa, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)

View File

@ -828,6 +828,13 @@ QualType ASTContext::getObjCGCQualType(QualType T,
if (CanT.getObjCGCAttr() == GCAttr)
return T;
if (T->isPointerType()) {
QualType Pointee = T->getAsPointerType()->getPointeeType();
if (Pointee->isPointerType()) {
QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
return getPointerType(ResultType);
}
}
// If we are composing extended qualifiers together, merge together into one
// ExtQualType node.
unsigned CVRQuals = T.getCVRQualifiers();

View File

@ -189,43 +189,6 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
E->arg_begin(), E->arg_end());
}
void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
llvm::Value *Ptr) {
LiveTemporaries.push_back(Temporary);
// Make a cleanup scope and emit the destructor.
{
CleanupScope Scope(*this);
EmitCXXDestructorCall(Temporary->getDestructor(), Dtor_Complete, Ptr);
}
}
RValue
CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
llvm::Value *AggLoc,
bool isAggLocVolatile) {
// Keep track of the current cleanup stack depth.
size_t CleanupStackDepth = CleanupEntries.size();
unsigned OldNumLiveTemporaries = LiveTemporaries.size();
RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
// Go through the temporaries backwards.
for (unsigned i = E->getNumTemporaries(); i != 0; --i) {
assert(LiveTemporaries.back() == E->getTemporary(i - 1));
LiveTemporaries.pop_back();
}
assert(OldNumLiveTemporaries == LiveTemporaries.size() &&
"Live temporary stack mismatch!");
EmitCleanupBlocks(CleanupStackDepth);
return RV;
}
llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
if (E->isArray()) {
ErrorUnsupported(E, "new[] expression");

67
lib/CodeGen/CGCXXTemp.cpp Normal file
View File

@ -0,0 +1,67 @@
//===--- CGCXXTemp.cpp - Emit LLVM Code for C++ temporaries ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code dealing with C++ code generation of temporaries
//
//===----------------------------------------------------------------------===//
#include "CodeGenFunction.h"
using namespace clang;
using namespace CodeGen;
void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
llvm::Value *Ptr) {
llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor");
LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock, 0));
}
void CodeGenFunction::PopCXXTemporary() {
const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();
CleanupBlockInfo CleanupInfo = PopCleanupBlock();
assert(CleanupInfo.CleanupBlock == Info.DtorBlock &&
"Cleanup block mismatch!");
assert(!CleanupInfo.SwitchBlock &&
"Should not have a switch block for temporary cleanup!");
assert(!CleanupInfo.EndBlock &&
"Should not have an end block for temporary cleanup!");
EmitBlock(Info.DtorBlock);
EmitCXXDestructorCall(Info.Temporary->getDestructor(),
Dtor_Complete, Info.ThisPtr);
LiveTemporaries.pop_back();
}
RValue
CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
llvm::Value *AggLoc,
bool isAggLocVolatile) {
// Keep track of the current cleanup stack depth.
size_t CleanupStackDepth = CleanupEntries.size();
unsigned OldNumLiveTemporaries = LiveTemporaries.size();
RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
// Go through the temporaries backwards.
for (unsigned i = E->getNumTemporaries(); i != 0; --i) {
assert(LiveTemporaries.back().Temporary == E->getTemporary(i - 1));
LiveTemporaries.pop_back();
}
assert(OldNumLiveTemporaries == LiveTemporaries.size() &&
"Live temporary stack mismatch!");
EmitCleanupBlocks(CleanupStackDepth);
return RV;
}

View File

@ -166,12 +166,12 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
void AggExprEmitter::VisitCStyleCastExpr(CStyleCastExpr *E) {
// GCC union extension
if (E->getType()->isUnionType()) {
RecordDecl *SD = E->getType()->getAsRecordType()->getDecl();
LValue FieldLoc = CGF.EmitLValueForField(DestPtr,
*SD->field_begin(CGF.getContext()),
true, 0);
EmitInitializationToLValue(E->getSubExpr(), FieldLoc);
if (E->getSubExpr()->getType()->isScalarType()) {
QualType PtrTy =
CGF.getContext().getPointerType(E->getSubExpr()->getType());
llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
CGF.ConvertType(PtrTy));
EmitInitializationToLValue(E->getSubExpr(), LValue::MakeAddr(CastPtr, 0));
return;
}

View File

@ -239,7 +239,30 @@ private:
/// 'this' declaration.
ImplicitParamDecl *CXXThisDecl;
llvm::SmallVector<const CXXTemporary*, 4> LiveTemporaries;
/// CXXLiveTemporaryInfo - Holds information about a live C++ temporary.
struct CXXLiveTemporaryInfo {
/// Temporary - The live temporary.
const CXXTemporary *Temporary;
/// ThisPtr - The pointer to the temporary.
llvm::Value *ThisPtr;
/// DtorBlock - The destructor block.
llvm::BasicBlock *DtorBlock;
/// CondPtr - If this is a conditional temporary, this is the pointer to
/// the condition variable that states whether the destructor should be
/// called or not.
llvm::Value *CondPtr;
CXXLiveTemporaryInfo(const CXXTemporary *temporary,
llvm::Value *thisptr, llvm::BasicBlock *dtorblock,
llvm::Value *condptr)
: Temporary(temporary), ThisPtr(thisptr), DtorBlock(dtorblock),
CondPtr(condptr) { }
};
llvm::SmallVector<CXXLiveTemporaryInfo, 4> LiveTemporaries;
public:
CodeGenFunction(CodeGenModule &cgm);
@ -483,6 +506,7 @@ public:
llvm::Value *This);
void PushCXXTemporary(const CXXTemporary *Temporary, llvm::Value *Ptr);
void PopCXXTemporary();
llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);

View File

@ -194,11 +194,13 @@ ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
std::string Arch = getArchName();
ArchName = Arch.c_str();
if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
if (getArchName() == "i386" || getArchName() == "x86_64") {
ArchName =
if (Triple.getArch() == llvm::Triple::x86 ||
Triple.getArch() == llvm::Triple::x86_64) {
ArchName =
(A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
} else if (getArchName() == "powerpc" || getArchName() == "powerpc64") {
ArchName =
} else if (Triple.getArch() == llvm::Triple::ppc ||
Triple.getArch() == llvm::Triple::ppc64) {
ArchName =
(A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
}
}
@ -361,13 +363,26 @@ ToolChain *LinuxHostInfo::getToolChain(const ArgList &Args,
assert(!ArchName &&
"Unexpected arch name on platform without driver driver support.");
ArchName = getArchName().c_str();
// Automatically handle some instances of -m32/-m64 we know about.
std::string Arch = getArchName();
ArchName = Arch.c_str();
if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
if (Triple.getArch() == llvm::Triple::x86 ||
Triple.getArch() == llvm::Triple::x86_64) {
ArchName =
(A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
} else if (Triple.getArch() == llvm::Triple::ppc ||
Triple.getArch() == llvm::Triple::ppc64) {
ArchName =
(A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
}
}
ToolChain *&TC = ToolChains[ArchName];
if (!TC) {
llvm::Triple TCTriple(getTriple());
TCTriple.setArchName(getArchName());
TCTriple.setArchName(ArchName);
TC = new toolchains::Linux(*this, TCTriple);
}

View File

@ -562,6 +562,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_dD);
Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
Args.AddAllArgValues(CmdArgs, options::OPT_mllvm);
if (Output.getType() == types::TY_Dependencies) {
// Handled with other dependency code.

View File

@ -26,6 +26,7 @@
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/Timer.h"
#include "llvm/System/Path.h"
#include "llvm/System/Program.h"
@ -33,8 +34,6 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/IPO.h"
using namespace clang;
using namespace llvm;
@ -265,99 +264,31 @@ void BackendConsumer::CreatePasses() {
if (CompileOpts.VerifyModule)
getPerFunctionPasses()->add(createVerifierPass());
if (CompileOpts.OptimizationLevel > 0) {
FunctionPassManager *PM = getPerFunctionPasses();
PM->add(createCFGSimplificationPass());
if (CompileOpts.OptimizationLevel == 1)
PM->add(createPromoteMemoryToRegisterPass());
else
PM->add(createScalarReplAggregatesPass());
PM->add(createInstructionCombiningPass());
// Assume that standard function passes aren't run for -O0.
if (CompileOpts.OptimizationLevel > 0)
llvm::createStandardFunctionPasses(getPerFunctionPasses(),
CompileOpts.OptimizationLevel);
llvm::Pass *InliningPass = 0;
switch (CompileOpts.Inlining) {
case CompileOptions::NoInlining: break;
case CompileOptions::NormalInlining:
InliningPass = createFunctionInliningPass(); // Inline small functions
break;
case CompileOptions::OnlyAlwaysInlining:
InliningPass = createAlwaysInlinerPass(); // Respect always_inline
break;
}
// For now we always create per module passes.
PassManager *PM = getPerModulePasses();
if (CompileOpts.OptimizationLevel > 0) {
if (CompileOpts.UnitAtATime)
PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst
PM->add(createCFGSimplificationPass()); // Clean up disgusting code
PM->add(createPromoteMemoryToRegisterPass()); // Kill useless allocas
if (CompileOpts.UnitAtATime) {
PM->add(createGlobalOptimizerPass()); // Optimize out global vars
PM->add(createGlobalDCEPass()); // Remove unused fns and globs
PM->add(createIPConstantPropagationPass()); // IP Constant Propagation
PM->add(createDeadArgEliminationPass()); // Dead argument elimination
}
PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE
PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
if (CompileOpts.UnitAtATime) {
PM->add(createPruneEHPass()); // Remove dead EH info
PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs
}
switch (CompileOpts.Inlining) {
case CompileOptions::NoInlining:
break;
case CompileOptions::NormalInlining:
PM->add(createFunctionInliningPass()); // Inline small functions
break;
case CompileOptions::OnlyAlwaysInlining:
PM->add(createAlwaysInlinerPass()); // Respect always_inline
break;
}
if (CompileOpts.OptimizationLevel > 2)
PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args
if (CompileOpts.SimplifyLibCalls)
PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations
PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
PM->add(createJumpThreadingPass()); // Thread jumps.
PM->add(createCFGSimplificationPass()); // Merge & remove BBs
PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas
PM->add(createInstructionCombiningPass()); // Combine silly seq's
PM->add(createCondPropagationPass()); // Propagate conditionals
PM->add(createTailCallEliminationPass()); // Eliminate tail calls
PM->add(createCFGSimplificationPass()); // Merge & remove BBs
PM->add(createReassociatePass()); // Reassociate expressions
PM->add(createLoopRotatePass()); // Rotate Loop
PM->add(createLICMPass()); // Hoist loop invariants
PM->add(createLoopUnswitchPass(CompileOpts.OptimizeSize ? true : false));
// PM->add(createLoopIndexSplitPass()); // Split loop index
PM->add(createInstructionCombiningPass());
PM->add(createIndVarSimplifyPass()); // Canonicalize indvars
PM->add(createLoopDeletionPass()); // Delete dead loops
if (CompileOpts.UnrollLoops)
PM->add(createLoopUnrollPass()); // Unroll small loops
PM->add(createInstructionCombiningPass()); // Clean up after the unroller
PM->add(createGVNPass()); // Remove redundancies
PM->add(createMemCpyOptPass()); // Remove memcpy / form memset
PM->add(createSCCPPass()); // Constant prop with SCCP
// Run instcombine after redundancy elimination to exploit opportunities
// opened up by them.
PM->add(createInstructionCombiningPass());
PM->add(createCondPropagationPass()); // Propagate conditionals
PM->add(createDeadStoreEliminationPass()); // Delete dead stores
PM->add(createAggressiveDCEPass()); // Delete dead instructions
PM->add(createCFGSimplificationPass()); // Merge & remove BBs
if (CompileOpts.UnitAtATime) {
PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
PM->add(createDeadTypeEliminationPass()); // Eliminate dead types
}
if (CompileOpts.OptimizationLevel > 1 && CompileOpts.UnitAtATime)
PM->add(createConstantMergePass()); // Merge dup global constants
} else {
switch (CompileOpts.Inlining) {
case CompileOptions::NoInlining:
break;
case CompileOptions::NormalInlining:
PM->add(createFunctionInliningPass()); // Inline small functions
break;
case CompileOptions::OnlyAlwaysInlining:
PM->add(createAlwaysInlinerPass()); // Respect always_inline
break;
}
}
llvm::createStandardModulePasses(PM, CompileOpts.OptimizationLevel,
CompileOpts.OptimizeSize,
CompileOpts.UnitAtATime,
CompileOpts.UnrollLoops,
CompileOpts.SimplifyLibCalls,
/*HaveExceptions=*/true,
InliningPass);
}
/// EmitAssembly - Handle interaction with LLVM backend to generate
@ -367,7 +298,6 @@ void BackendConsumer::EmitAssembly() {
if (!TheModule || !TheTargetData)
return;
TimeRegion Region(CompileOpts.TimePasses ? &CodeGenerationTime : 0);
// Make sure IR generation is happy with the module. This is

View File

@ -129,15 +129,15 @@ template <typename T>
static T PickFP(const llvm::fltSemantics *Sem, T IEEESingleVal,
T IEEEDoubleVal, T X87DoubleExtendedVal, T PPCDoubleDoubleVal,
T IEEEQuadVal) {
if (Sem == &llvm::APFloat::IEEEsingle)
if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle)
return IEEESingleVal;
if (Sem == &llvm::APFloat::IEEEdouble)
if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEdouble)
return IEEEDoubleVal;
if (Sem == &llvm::APFloat::x87DoubleExtended)
if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::x87DoubleExtended)
return X87DoubleExtendedVal;
if (Sem == &llvm::APFloat::PPCDoubleDouble)
if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::PPCDoubleDouble)
return PPCDoubleDoubleVal;
assert(Sem == &llvm::APFloat::IEEEquad);
assert(Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEquad);
return IEEEQuadVal;
}

View File

@ -101,6 +101,11 @@ extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn stat
CFTypeRef CFMakeCollectable(CFTypeRef cf) ;
static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef
cf) {
return cf ? (id)CFMakeCollectable(cf) : ((void*)0);
}
//===----------------------------------------------------------------------===//
// Test cases.
//===----------------------------------------------------------------------===//
@ -124,6 +129,31 @@ void f3() {
CFRetain(A);
}
void f3b() {
CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
CFMakeCollectable(A);
}
void f4() {
CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
NSMakeCollectable(A);
CFRetain(A);
}
void f4b() {
CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
NSMakeCollectable(A);
}
void f5() {
id x = [NSMakeCollectable(CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks)) autorelease]; // no-warning
}
void f5b() {
id x = [(id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks) autorelease]; // expected-warning{{leak}}
}
// Test return of non-owned objects in contexts where an owned object
// is expected.
@interface TestReturnNotOwnedWhenExpectedOwned
@ -133,7 +163,7 @@ void f3() {
@implementation TestReturnNotOwnedWhenExpectedOwned
- (NSString*)newString {
NSString *s = [NSString stringWithUTF8String:"hello"]; // expected-warning{{Potential leak (when using garbage collection) of an object allocated on line 136 and stored into 's'}}
NSString *s = [NSString stringWithUTF8String:"hello"]; // expected-warning{{Potential leak (when using garbage collection) of an object allocated}}
CFRetain(s);
return s;
}

View File

@ -1,6 +1,6 @@
// RUN: clang-cc -emit-llvm -o %t %s &&
// RUN: clang -emit-llvm -S -o %t %s &&
// RUN: grep '@f0' %t | count 0 &&
// RUN: clang-cc -disable-llvm-optzns -emit-llvm -o %t %s &&
// RUN: clang -mllvm -disable-llvm-optzns -emit-llvm -S -o %t %s &&
// RUN: grep '@f0' %t | count 2
//static int f0() {

View File

@ -7,6 +7,7 @@ union u { int i; double d; };
void foo() {
union u ola = (union u) 351;
union u olb = (union u) 1.0;
}
union u w = (union u)2;

View File

@ -0,0 +1,22 @@
// RUN: clang-cc -triple x86_64-apple-darwin9 -fobjc-gc -emit-llvm -o %t %s &&
// RUN: grep -e "objc_assign_weak" %t | grep -e "call" | count 6
__weak id* x;
id* __weak y;
id* __weak* z;
__weak id* a1[20];
id* __weak a2[30];
id** __weak a3[40];
int main()
{
*x = 0;
*y = 0;
**z = 0;
a1[3] = 0;
a2[3] = 0;
a3[3][4] = 0;
}