Import Clang, at r72805.
This commit is contained in:
parent
48ecc7affe
commit
9e262ca77e
@ -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;
|
||||
};
|
||||
|
@ -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 |
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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
67
lib/CodeGen/CGCXXTemp.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
22
test/CodeGenObjC/objc2-weak-assign.m
Normal file
22
test/CodeGenObjC/objc2-weak-assign.m
Normal 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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user