Update clang to r97873.

This commit is contained in:
Roman Divacky 2010-03-06 09:23:02 +00:00
parent 79ade4e028
commit dd5132ce25
84 changed files with 1498 additions and 245 deletions

View File

@ -48,11 +48,11 @@ generated:: doxygen
install-html: $(PROJ_OBJ_DIR)/html.tar.gz
$(Echo) Installing HTML documentation
$(Verb) $(MKDIR) $(PROJ_docsdir)/html
$(Verb) $(MKDIR) $(PROJ_docsdir)/html/img
$(Verb) $(DataInstall) $(HTML) $(PROJ_docsdir)/html
# $(Verb) $(DataInstall) $(IMAGES) $(PROJ_docsdir)/html/img
$(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/html.tar.gz $(PROJ_docsdir)
$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html
$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html/img
$(Verb) $(DataInstall) $(HTML) $(DESTDIR)$(PROJ_docsdir)/html
# $(Verb) $(DataInstall) $(IMAGES) $(DESTDIR)$(PROJ_docsdir)/html/img
$(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/html.tar.gz $(DESTDIR)$(PROJ_docsdir)
$(PROJ_OBJ_DIR)/html.tar.gz: $(HTML)
$(Echo) Packaging HTML documentation
@ -63,11 +63,11 @@ $(PROJ_OBJ_DIR)/html.tar.gz: $(HTML)
install-doxygen: doxygen
$(Echo) Installing doxygen documentation
$(Verb) $(MKDIR) $(PROJ_docsdir)/html/doxygen
$(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(PROJ_docsdir)
$(Verb) $(MKDIR) $(DESTDIR)$(PROJ_docsdir)/html/doxygen
$(Verb) $(DataInstall) $(PROJ_OBJ_DIR)/doxygen.tar.gz $(DESTDIR)$(PROJ_docsdir)
$(Verb) cd $(PROJ_OBJ_DIR)/doxygen && \
$(FIND) . -type f -exec \
$(DataInstall) {} $(PROJ_docsdir)/html/doxygen \;
$(DataInstall) {} $(DESTDIR)$(PROJ_docsdir)/html/doxygen \;
doxygen: regendoc $(PROJ_OBJ_DIR)/doxygen.tar.gz
@ -94,4 +94,4 @@ $(LLVM_SRC_ROOT)/docs/userloc.html:
uninstall-local::
$(Echo) Uninstalling Documentation
$(Verb) $(RM) -rf $(PROJ_docsdir)
$(Verb) $(RM) -rf $(DESTDIR)$(PROJ_docsdir)

View File

@ -84,9 +84,9 @@ EXTRA_DIST := $(POD)
clean-local::
$(Verb) $(RM) -f pod2htm*.*~~ $(HTML) $(MAN) $(PS)
HTML_DIR := $(PROJ_docsdir)/html/clang
MAN_DIR := $(PROJ_mandir)/man1
PS_DIR := $(PROJ_docsdir)/ps
HTML_DIR := $(DESTDIR)$(PROJ_docsdir)/html/clang
MAN_DIR := $(DESTDIR)$(PROJ_mandir)/man1
PS_DIR := $(DESTDIR)$(PROJ_docsdir)/ps
install-html:: $(HTML)
$(Echo) Installing HTML Clang Tools Documentation

View File

@ -621,7 +621,8 @@ class ASTContext {
/// given interface decl and the conforming protocol list.
QualType getObjCObjectPointerType(QualType OIT,
ObjCProtocolDecl **ProtocolList = 0,
unsigned NumProtocols = 0);
unsigned NumProtocols = 0,
unsigned Quals = 0);
/// getTypeOfType - GCC extension.
QualType getTypeOfExprType(Expr *e);

View File

@ -268,7 +268,7 @@ class Decl {
/// setInvalidDecl - Indicates the Decl had a semantic error. This
/// allows for graceful error recovery.
void setInvalidDecl(bool Invalid = true) { InvalidDecl = Invalid; }
void setInvalidDecl(bool Invalid = true);
bool isInvalidDecl() const { return (bool) InvalidDecl; }
/// isImplicit - Indicates whether the declaration was implicitly

View File

@ -240,6 +240,11 @@ BUILTIN(__builtin_isinf_sign, "i.", "nc")
BUILTIN(__builtin_isnan, "i.", "nc")
BUILTIN(__builtin_isnormal, "i.", "nc")
// FP signbit builtins
BUILTIN(__builtin_signbit, "id", "nc")
BUILTIN(__builtin_signbitf, "if", "nc")
BUILTIN(__builtin_signbitl, "iLd", "nc")
// Builtins for arithmetic.
BUILTIN(__builtin_clz , "iUi" , "nc")
BUILTIN(__builtin_clzl , "iULi" , "nc")

View File

@ -0,0 +1,20 @@
//===--- BuiltinsARM.def - ARM Builtin function database ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the ARM-specific builtin function database. Users of
// this file must define the BUILTIN macro to make use of this information.
//
//===----------------------------------------------------------------------===//
// The format of this database matches clang/Basic/Builtins.def.
// FIXME: This is just a placeholder. NEON intrinsics should be listed here.
BUILTIN(__builtin_thread_pointer, "v*", "")
#undef BUILTIN

View File

@ -281,8 +281,8 @@ BUILTIN(__builtin_ia32_pmovzxwq128, "V2LLiV8s", "")
BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "")
BUILTIN(__builtin_ia32_pmulld128, "V4iV4iV4i", "")
BUILTIN(__builtin_ia32_roundps, "V4fV4fi", "")
BUILTIN(__builtin_ia32_roundss, "V4fV4fi", "")
BUILTIN(__builtin_ia32_roundsd, "V2dV2di", "")
BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fi", "")
BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2di", "")
BUILTIN(__builtin_ia32_roundpd, "V2dV2di", "")

View File

@ -1587,11 +1587,12 @@ def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
def err_goto_into_protected_scope : Error<"illegal goto into protected scope">;
def err_switch_into_protected_scope : Error<
"illegal switch case into protected scope">;
def err_indirect_goto_in_protected_scope : Error<
"illegal indirect goto in protected scope, unknown effect on scopes">;
def err_addr_of_label_in_protected_scope : Error<
def err_indirect_goto_in_protected_scope : Warning<
"illegal indirect goto in protected scope, unknown effect on scopes">,
InGroup<DiagGroup<"label-address-scope">>;
def err_addr_of_label_in_protected_scope : Warning<
"address taken of label in protected scope, jump to it would have "
"unknown effect on scope">;
"unknown effect on scope">, InGroup<DiagGroup<"label-address-scope">>;
def note_protected_by_variable_init : Note<
"jump bypasses variable initialization">;
def note_protected_by_vla_typedef : Note<

View File

@ -14,12 +14,13 @@
#undef PPC
namespace clang {
/// X86 builtins
namespace X86 {
/// ARM builtins
namespace ARM {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsX86.def"
#include "clang/Basic/BuiltinsARM.def"
LastTSBuiltin
};
}
@ -33,6 +34,17 @@ namespace clang {
LastTSBuiltin
};
}
/// X86 builtins
namespace X86 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsX86.def"
LastTSBuiltin
};
}
} // end namespace clang.
#endif

View File

@ -336,8 +336,6 @@ KEYWORD(__declspec , KEYALL)
KEYWORD(__cdecl , KEYALL)
KEYWORD(__stdcall , KEYALL)
KEYWORD(__fastcall , KEYALL)
KEYWORD(__ptr64 , KEYALL)
KEYWORD(__w64 , KEYALL)
KEYWORD(__forceinline , KEYALL)
// Altivec Extension.
@ -368,6 +366,8 @@ ALIAS("__volatile" , volatile , KEYALL)
ALIAS("__volatile__" , volatile , KEYALL)
// Microsoft extensions which should be disabled in strict conformance mode
KEYWORD(__ptr64 , KEYMS)
KEYWORD(__w64 , KEYMS)
ALIAS("_asm" , asm , KEYMS)
ALIAS("_cdecl" , __cdecl , KEYMS)
ALIAS("_fastcall" , __fastcall , KEYMS)

View File

@ -26,7 +26,6 @@
namespace clang {
class AnalysisContext;
class EnvironmentManager;
class ValueManager;
class LiveVariables;
@ -41,10 +40,9 @@ class Environment {
// Data.
BindingsTy ExprBindings;
AnalysisContext *ACtx;
Environment(BindingsTy eb, AnalysisContext *aCtx)
: ExprBindings(eb), ACtx(aCtx) {}
Environment(BindingsTy eb)
: ExprBindings(eb) {}
public:
typedef BindingsTy::iterator iterator;
@ -58,8 +56,6 @@ class Environment {
SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const;
AnalysisContext &getAnalysisContext() const { return *ACtx; }
/// Profile - Profile the contents of an Environment object for use
/// in a FoldingSet.
static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
@ -86,8 +82,8 @@ class EnvironmentManager {
EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
~EnvironmentManager() {}
Environment getInitialEnvironment(AnalysisContext *ACtx) {
return Environment(F.GetEmptyMap(), ACtx);
Environment getInitialEnvironment() {
return Environment(F.GetEmptyMap());
}
Environment BindExpr(Environment Env, const Stmt *S, SVal V,

View File

@ -109,12 +109,6 @@ class GRState : public llvm::FoldingSetNode {
return *StateMgr;
}
/// getAnalysisContext - Return the AnalysisContext associated with this
/// state.
AnalysisContext &getAnalysisContext() const {
return Env.getAnalysisContext();
}
/// getEnvironment - Return the environment associated with this state.
/// The environment is the mapping from expressions to values.
const Environment& getEnvironment() const { return Env; }
@ -133,7 +127,6 @@ class GRState : public llvm::FoldingSetNode {
/// Profile - Profile the contents of a GRState object for use
/// in a FoldingSet.
static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) {
// FIXME: Do we need to include the AnalysisContext in the profile?
V->Env.Profile(ID);
ID.AddPointer(V->St);
V->GDM.Profile(ID);
@ -337,12 +330,12 @@ class GRState : public llvm::FoldingSetNode {
};
// Pretty-printing.
void print(llvm::raw_ostream& Out, const char *nl = "\n",
void print(llvm::raw_ostream& Out, CFG &C, const char *nl = "\n",
const char *sep = "") const;
void printStdErr() const;
void printStdErr(CFG &C) const;
void printDOT(llvm::raw_ostream& Out) const;
void printDOT(llvm::raw_ostream& Out, CFG &C) const;
};
class GRStateSet {

View File

@ -331,23 +331,20 @@ class SymbolReaper {
SetTy TheLiving;
SetTy TheDead;
LiveVariables& Liveness;
const LocationContext *LCtx;
SymbolManager& SymMgr;
const StackFrameContext *CurrentStackFrame;
public:
SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr,
const StackFrameContext *currentStackFrame)
: Liveness(liveness), SymMgr(symmgr), CurrentStackFrame(currentStackFrame)
{}
SymbolReaper(const LocationContext *ctx, SymbolManager& symmgr)
: LCtx(ctx), SymMgr(symmgr) {}
~SymbolReaper() {}
const LocationContext *getLocationContext() const { return LCtx; }
bool isLive(SymbolRef sym);
bool isLive(const Stmt* Loc, const Stmt* ExprVal) const {
return Liveness.isLive(Loc, ExprVal);
}
bool isLive(const Stmt* Loc, const Stmt* ExprVal) const;
bool isLive(const Stmt* Loc, const VarRegion *VR) const;

View File

@ -80,6 +80,8 @@ const HostInfo *createDragonFlyHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createLinuxHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createTCEHostInfo(const Driver &D,
const llvm::Triple& Triple);
const HostInfo *createUnknownHostInfo(const Driver &D,
const llvm::Triple& Triple);

View File

@ -64,6 +64,7 @@ def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
// , => _COMMA
// = => _EQ
// C++ => CXX
// . => _
// Developer Driver Options
@ -420,6 +421,8 @@ def mno_sse2 : Flag<"-mno-sse2">, Group<m_x86_Features_Group>;
def mno_sse3 : Flag<"-mno-sse3">, Group<m_x86_Features_Group>;
def mno_sse4a : Flag<"-mno-sse4a">, Group<m_x86_Features_Group>;
def mno_sse4 : Flag<"-mno-sse4">, Group<m_x86_Features_Group>;
def mno_sse4_1 : Flag<"-mno-sse4.1">, Group<m_x86_Features_Group>;
def mno_sse4_2 : Flag<"-mno-sse4.2">, Group<m_x86_Features_Group>;
def mno_sse : Flag<"-mno-sse">, Group<m_x86_Features_Group>;
def mno_ssse3 : Flag<"-mno-ssse3">, Group<m_x86_Features_Group>;
@ -434,6 +437,8 @@ def msse2 : Flag<"-msse2">, Group<m_x86_Features_Group>;
def msse3 : Flag<"-msse3">, Group<m_x86_Features_Group>;
def msse4a : Flag<"-msse4a">, Group<m_x86_Features_Group>;
def msse4 : Flag<"-msse4">, Group<m_x86_Features_Group>;
def msse4_1 : Flag<"-msse4.1">, Group<m_x86_Features_Group>;
def msse4_2 : Flag<"-msse4.2">, Group<m_x86_Features_Group>;
def msse : Flag<"-msse">, Group<m_x86_Features_Group>;
def mssse3 : Flag<"-mssse3">, Group<m_x86_Features_Group>;
def mthumb : Flag<"-mthumb">, Group<m_Group>;

View File

@ -88,11 +88,39 @@ class ASTUnit {
/// \brief Temporary files that should be removed when the ASTUnit is
/// destroyed.
llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles;
/// \brief Simple hack to allow us to assert that ASTUnit is not being
/// used concurrently, which is not supported.
///
/// Clients should create instances of the ConcurrencyCheck class whenever
/// using the ASTUnit in a way that isn't intended to be concurrent, which is
/// just about any usage.
unsigned int ConcurrencyCheckValue;
static const unsigned int CheckLocked = 28573289;
static const unsigned int CheckUnlocked = 9803453;
ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
public:
class ConcurrencyCheck {
volatile ASTUnit &Self;
public:
explicit ConcurrencyCheck(ASTUnit &Self)
: Self(Self)
{
assert(Self.ConcurrencyCheckValue == CheckUnlocked &&
"Concurrent access to ASTUnit!");
Self.ConcurrencyCheckValue = CheckLocked;
}
~ConcurrencyCheck() {
Self.ConcurrencyCheckValue = CheckUnlocked;
}
};
friend class ConcurrencyCheck;
ASTUnit(bool MainFileIsAST);
~ASTUnit();

View File

@ -2240,14 +2240,16 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols,
/// the given interface decl and the conforming protocol list.
QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
ObjCProtocolDecl **Protocols,
unsigned NumProtocols) {
unsigned NumProtocols,
unsigned Quals) {
llvm::FoldingSetNodeID ID;
ObjCObjectPointerType::Profile(ID, InterfaceT, Protocols, NumProtocols);
Qualifiers Qs = Qualifiers::fromCVRMask(Quals);
void *InsertPos = 0;
if (ObjCObjectPointerType *QT =
ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(QT, 0);
return getQualifiedType(QualType(QT, 0), Qs);
// Sort the protocol list alphabetically to canonicalize it.
QualType Canonical;
@ -2282,7 +2284,7 @@ QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
Types.push_back(QType);
ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
return QualType(QType, 0);
return getQualifiedType(QualType(QType, 0), Qs);
}
/// getObjCInterfaceType - Return the unique reference to the type for the

View File

@ -46,6 +46,16 @@ const char *Decl::getDeclKindName() const {
}
}
void Decl::setInvalidDecl(bool Invalid) {
InvalidDecl = Invalid;
if (Invalid) {
// Defensive maneuver for ill-formed code: we're likely not to make it to
// a point where we set the access specifier, so default it to "public"
// to avoid triggering asserts elsewhere in the front end.
setAccess(AS_public);
}
}
const char *DeclContext::getDeclKindName() const {
switch (DeclKind) {
default: assert(0 && "Declaration context not in DeclNodes.def!");

View File

@ -734,8 +734,10 @@ void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
const std::string &Name,
bool Enabled) const {
// FIXME: This *really* should not be here.
if (!Features.count(Name) && Name != "sse4")
// FIXME: This *really* should not be here. We need some way of translating
// options into llvm subtarget features.
if (!Features.count(Name) &&
(Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
return false;
if (Enabled) {
@ -751,9 +753,12 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
else if (Name == "ssse3")
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Features["ssse3"] = true;
else if (Name == "sse4")
else if (Name == "sse4" || Name == "sse4.2")
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
else if (Name == "sse4.1")
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Features["ssse3"] = Features["sse41"] = true;
else if (Name == "3dnow")
Features["3dnowa"] = true;
else if (Name == "3dnowa")
@ -775,6 +780,10 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
else if (Name == "sse4")
Features["sse41"] = Features["sse42"] = false;
else if (Name == "sse4.2")
Features["sse42"] = false;
else if (Name == "sse4.1")
Features["sse41"] = Features["sse42"] = false;
else if (Name == "3dnow")
Features["3dnow"] = Features["3dnowa"] = false;
else if (Name == "3dnowa")
@ -1207,6 +1216,8 @@ class ARMTargetInfo : public TargetInfo {
unsigned SoftFloat : 1;
unsigned SoftFloatABI : 1;
static const Builtin::Info BuiltinInfo[];
public:
ARMTargetInfo(const std::string &TripleStr)
: TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
@ -1393,9 +1404,8 @@ class ARMTargetInfo : public TargetInfo {
}
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {
// FIXME: Implement.
Records = 0;
NumRecords = 0;
Records = BuiltinInfo;
NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
}
virtual const char *getVAListDeclaration() const {
return "typedef char* __builtin_va_list;";
@ -1460,6 +1470,12 @@ void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Aliases = GCCRegAliases;
NumAliases = llvm::array_lengthof(GCCRegAliases);
}
const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
#include "clang/Basic/BuiltinsARM.def"
};
} // end anonymous namespace.
@ -1892,9 +1908,10 @@ namespace {
FloatFormat = &llvm::APFloat::IEEEsingle;
DoubleFormat = &llvm::APFloat::IEEEsingle;
LongDoubleFormat = &llvm::APFloat::IEEEsingle;
DescriptionString = "E-p:32:32:32-a0:32:32"
"-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64"
"-f32:32:32-f64:32:64-n32";
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
"i16:16:32-i32:32:32-i64:32:32-"
"f32:32:32-f64:64:64-v64:64:64-"
"v128:128:128-a0:0:64-n32";
}
virtual void getTargetDefines(const LangOptions &Opts,

View File

@ -45,7 +45,7 @@ std::string getClangRevision() {
std::string revision;
llvm::raw_string_ostream OS(revision);
OS << strtol(SVN_REVISION, 0, 10);
return revision;
return OS.str();
}
#endif
return "";
@ -58,7 +58,7 @@ std::string getClangFullRepositoryVersion() {
const std::string &Revision = getClangRevision();
if (!Revision.empty())
OS << ' ' << Revision;
return buf;
return OS.str();
}
std::string getClangFullVersion() {
@ -69,7 +69,7 @@ std::string getClangFullVersion() {
#endif
OS << "clang version " CLANG_VERSION_STRING " ("
<< getClangFullRepositoryVersion() << ')';
return buf;
return OS.str();
}
} // end namespace clang

View File

@ -78,12 +78,12 @@ Environment EnvironmentManager::BindExpr(Environment Env, const Stmt *S,
if (V.isUnknown()) {
if (Invalidate)
return Environment(F.Remove(Env.ExprBindings, S), Env.ACtx);
return Environment(F.Remove(Env.ExprBindings, S));
else
return Env;
}
return Environment(F.Add(Env.ExprBindings, S, V), Env.ACtx);
return Environment(F.Add(Env.ExprBindings, S, V));
}
namespace {
@ -109,12 +109,12 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
const GRState *ST,
llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
CFG &C = *Env.getAnalysisContext().getCFG();
CFG &C = *SymReaper.getLocationContext()->getCFG();
// We construct a new Environment object entirely, as this is cheaper than
// individually removing all the subexpression bindings (which will greatly
// outnumber block-level expression bindings).
Environment NewEnv = getInitialEnvironment(&Env.getAnalysisContext());
Environment NewEnv = getInitialEnvironment();
// Iterate over the block-expr bindings.
for (Environment::iterator I = Env.begin(), E = Env.end();

View File

@ -477,8 +477,9 @@ void GRExprEngine::ProcessStmt(CFGElement CE, GRStmtNodeBuilder& builder) {
// Create the cleaned state.
const ExplodedNode *BasePred = Builder->getBasePredecessor();
SymbolReaper SymReaper(BasePred->getLiveVariables(), SymMgr,
BasePred->getLocationContext()->getCurrentStackFrame());
SymbolReaper SymReaper(BasePred->getLocationContext(), SymMgr);
CleanedState = AMgr.shouldPurgeDead()
? StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt, SymReaper)
: EntryNode->getState();
@ -3319,7 +3320,7 @@ struct DOTGraphTraits<ExplodedNode*> :
Out << "\\|StateID: " << (void*) N->getState() << "\\|";
const GRState *state = N->getState();
state->printDOT(Out);
state->printDOT(Out, *N->getLocationContext()->getCFG());
Out << "\\l";
return Out.str();

View File

@ -99,7 +99,7 @@ const GRState *GRState::BindExpr(const Stmt* Ex, SVal V, bool Invalidate) const{
const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) {
GRState State(this,
EnvMgr.getInitialEnvironment(InitLoc->getAnalysisContext()),
EnvMgr.getInitialEnvironment(),
StoreMgr->getInitialStore(InitLoc),
GDMFactory.GetEmptyMap());
@ -131,14 +131,12 @@ const GRState* GRState::makeWithStore(Store store) const {
// State pretty-printing.
//===----------------------------------------------------------------------===//
void GRState::print(llvm::raw_ostream& Out, const char* nl,
void GRState::print(llvm::raw_ostream& Out, CFG &C, const char* nl,
const char* sep) const {
// Print the store.
GRStateManager &Mgr = getStateManager();
Mgr.getStoreManager().print(getStore(), Out, nl, sep);
CFG &C = *getAnalysisContext().getCFG();
// Print Subexpression bindings.
bool isFirst = true;
@ -186,12 +184,12 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,
}
}
void GRState::printDOT(llvm::raw_ostream& Out) const {
print(Out, "\\l", "\\|");
void GRState::printDOT(llvm::raw_ostream& Out, CFG &C) const {
print(Out, C, "\\l", "\\|");
}
void GRState::printStdErr() const {
print(llvm::errs());
void GRState::printStdErr(CFG &C) const {
print(llvm::errs(), C);
}
//===----------------------------------------------------------------------===//

View File

@ -215,13 +215,17 @@ bool SymbolReaper::isLive(SymbolRef sym) {
return isa<SymbolRegionValue>(sym);
}
bool SymbolReaper::isLive(const Stmt* Loc, const Stmt* ExprVal) const {
return LCtx->getLiveVariables()->isLive(Loc, ExprVal);
}
bool SymbolReaper::isLive(const Stmt *Loc, const VarRegion *VR) const {
const StackFrameContext *SFC = VR->getStackFrame();
if (SFC == CurrentStackFrame)
return Liveness.isLive(Loc, VR->getDecl());
if (SFC == LCtx->getCurrentStackFrame())
return LCtx->getLiveVariables()->isLive(Loc, VR->getDecl());
else
return SFC->isParentOf(CurrentStackFrame);
return SFC->isParentOf(LCtx->getCurrentStackFrame());
}
SymbolVisitor::~SymbolVisitor() {}

View File

@ -154,7 +154,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
{
// C = BuildBlockStructInitlist();
unsigned int flags = BLOCK_HAS_OBJC_TYPE;
unsigned int flags = BLOCK_HAS_SIGNATURE;
// We run this first so that we set BlockHasCopyDispose from the entire
// block literal.
@ -184,6 +184,18 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
Elts[0] = C;
// __flags
{
QualType BPT = BE->getType();
const FunctionType *ftype = BPT->getPointeeType()->getAs<FunctionType>();
QualType ResultType = ftype->getResultType();
CallArgList Args;
CodeGenTypes &Types = CGM.getTypes();
const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, Args,
CC_Default, false);
if (CGM.ReturnTypeUsesSret(FnInfo))
flags |= BLOCK_USE_STRET;
}
const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
CGM.getTypes().ConvertType(CGM.getContext().IntTy));
C = llvm::ConstantInt::get(IntTy, flags);
@ -200,6 +212,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
// Optimize to being a global block.
Elts[0] = CGM.getNSConcreteGlobalBlock();
Elts[1] = llvm::ConstantInt::get(IntTy, flags|BLOCK_IS_GLOBAL);
C = llvm::ConstantStruct::get(VMContext, Elts, false);
@ -604,7 +617,7 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
// Flags
LiteralFields[1] =
llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_OBJC_TYPE);
llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE);
// Reserved
LiteralFields[2] = llvm::Constant::getNullValue(IntTy);

View File

@ -54,10 +54,12 @@ class BlockBase {
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
BLOCK_HAS_CXX_OBJ = (1 << 26),
BLOCK_IS_GLOBAL = (1 << 28),
BLOCK_HAS_OBJC_TYPE = (1 << 30)
BLOCK_USE_STRET = (1 << 29),
BLOCK_HAS_SIGNATURE = (1 << 30)
};
};
class BlockModule : public BlockBase {
ASTContext &Context;
llvm::Module &TheModule;

View File

@ -387,6 +387,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *Result = getTargetHooks().encodeReturnAddress(*this, Address);
return RValue::get(Result);
}
case Builtin::BI__builtin_dwarf_sp_column: {
const llvm::IntegerType *Ty
= cast<llvm::IntegerType>(ConvertType(E->getType()));
int Column = getTargetHooks().getDwarfEHStackPointer(CGM);
if (Column == -1) {
CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column");
return RValue::get(llvm::UndefValue::get(Ty));
}
return RValue::get(llvm::ConstantInt::get(Ty, Column, true));
}
case Builtin::BI__builtin_init_dwarf_reg_size_table: {
Value *Address = EmitScalarExpr(E->getArg(0));
if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address))
CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table");
return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
}
case Builtin::BI__builtin_eh_return: {
Value *Int = EmitScalarExpr(E->getArg(0));
Value *Ptr = EmitScalarExpr(E->getArg(1));
@ -666,6 +682,23 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1);
return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
}
case Builtin::BI__builtin_signbit:
case Builtin::BI__builtin_signbitf:
case Builtin::BI__builtin_signbitl: {
LLVMContext &C = CGM.getLLVMContext();
Value *Arg = EmitScalarExpr(E->getArg(0));
const llvm::Type *ArgTy = Arg->getType();
if (ArgTy->isPPC_FP128Ty())
break; // FIXME: I'm not sure what the right implementation is here.
int ArgWidth = ArgTy->getPrimitiveSizeInBits();
const llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth);
Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy);
Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy);
Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp);
return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType())));
}
}
// If this is an alias for a libm function (e.g. __builtin_sin) turn it into
@ -735,6 +768,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
switch (Target.getTriple().getArch()) {
case llvm::Triple::arm:
case llvm::Triple::thumb:
return EmitARMBuiltinExpr(BuiltinID, E);
case llvm::Triple::x86:
case llvm::Triple::x86_64:
return EmitX86BuiltinExpr(BuiltinID, E);
@ -746,6 +782,18 @@ Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
}
}
Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
switch (BuiltinID) {
default: return 0;
case ARM::BI__builtin_thread_pointer: {
Value *AtomF = CGM.getIntrinsic(Intrinsic::arm_thread_pointer, 0, 0);
return Builder.CreateCall(AtomF);
}
}
}
Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {

View File

@ -142,6 +142,12 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
return true;
}
llvm::GlobalValue::LinkageTypes TargetLinkage
= getFunctionLinkage(cast<FunctionDecl>(TargetDecl.getDecl()));
if (llvm::GlobalValue::isWeakForLinker(TargetLinkage))
return true;
// Derive the type for the alias.
const llvm::PointerType *AliasType
= getTypes().GetFunctionType(AliasDecl)->getPointerTo();

View File

@ -1062,6 +1062,16 @@ static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
const NamedDecl *ND = E->getDecl();
if (ND->hasAttr<WeakRefAttr>()) {
const ValueDecl* VD = cast<ValueDecl>(ND);
llvm::Constant *Aliasee = CGM.GetWeakRefReference(VD);
Qualifiers Quals = MakeQualifiers(E->getType());
LValue LV = LValue::MakeAddr(Aliasee, Quals);
return LV;
}
if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
// Check if this is a global variable.

View File

@ -761,7 +761,9 @@ class ConstExprEmitter :
return C;
}
case Expr::DeclRefExprClass: {
NamedDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
if (Decl->hasAttr<WeakRefAttr>())
return CGM.GetWeakRefReference(Decl);
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
return CGM.GetAddrOfFunction(FD);
if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {

View File

@ -1888,6 +1888,8 @@ LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
V = CreateTempAlloca(ClassPtrTy, "resval");
llvm::Value *Src = EmitScalarExpr(BaseExpr);
Builder.CreateStore(Src, V);
LValue LV = LValue::MakeAddr(V, MakeQualifiers(E->getType()));
V = ScalarExprEmitter(*this).EmitLoadOfLValue(LV, E->getType());
}
else {
if (E->isArrow())

View File

@ -915,18 +915,17 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
TargetInfo::ConstraintInfo Info(S.getOutputConstraint(i),
S.getOutputName(i));
assert(Target.validateOutputConstraint(Info) &&
"Failed to parse output constraint");
bool IsValid = Target.validateOutputConstraint(Info); (void)IsValid;
assert(IsValid && "Failed to parse output constraint");
OutputConstraintInfos.push_back(Info);
}
for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) {
TargetInfo::ConstraintInfo Info(S.getInputConstraint(i),
S.getInputName(i));
assert(Target.validateInputConstraint(OutputConstraintInfos.data(),
S.getNumOutputs(),
Info) &&
"Failed to parse input constraint");
bool IsValid = Target.validateInputConstraint(OutputConstraintInfos.data(),
S.getNumOutputs(), Info);
assert(IsValid && "Failed to parse input constraint"); (void)IsValid;
InputConstraintInfos.push_back(Info);
}

View File

@ -1122,6 +1122,7 @@ class CodeGenFunction : public BlockFunction {
/// is unhandled by the current target.
llvm::Value *EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);

View File

@ -33,6 +33,7 @@
#include "llvm/Module.h"
#include "llvm/Intrinsics.h"
#include "llvm/LLVMContext.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
@ -89,6 +90,10 @@ void CodeGenModule::Release() {
EmitLLVMUsed();
}
bool CodeGenModule::isTargetDarwin() const {
return getContext().Target.getTriple().getOS() == llvm::Triple::Darwin;
}
/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified stmt yet.
void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,
@ -619,9 +624,41 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
return false;
}
llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
const AliasAttr *AA = VD->getAttr<AliasAttr>();
assert(AA && "No alias?");
const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(VD->getType());
// Unique the name through the identifier table.
const char *AliaseeName =
getContext().Idents.get(AA->getAliasee()).getNameStart();
// See if there is already something with the target's name in the module.
llvm::GlobalValue *Entry = GlobalDeclMap[AliaseeName];
llvm::Constant *Aliasee;
if (isa<llvm::FunctionType>(DeclTy))
Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl());
else
Aliasee = GetOrCreateLLVMGlobal(AliaseeName,
llvm::PointerType::getUnqual(DeclTy), 0);
if (!Entry) {
llvm::GlobalValue* F = cast<llvm::GlobalValue>(Aliasee);
F->setLinkage(llvm::Function::ExternalWeakLinkage);
WeakRefReferences.insert(F);
}
return Aliasee;
}
void CodeGenModule::EmitGlobal(GlobalDecl GD) {
const ValueDecl *Global = cast<ValueDecl>(GD.getDecl());
// Weak references don't produce any output by themselves.
if (Global->hasAttr<WeakRefAttr>())
return;
// If this is an alias definition (which otherwise looks like a declaration)
// emit it now.
if (Global->hasAttr<AliasAttr>())
@ -708,6 +745,14 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
// Lookup the entry, lazily creating it if necessary.
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
if (Entry) {
if (WeakRefReferences.count(Entry)) {
const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl());
if (FD && !FD->hasAttr<WeakAttr>())
Entry->setLinkage(llvm::Function::ExternalLinkage);
WeakRefReferences.erase(Entry);
}
if (Entry->getType()->getElementType() == Ty)
return Entry;
@ -753,17 +798,17 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
// synthesized.
else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
if (CD->isImplicit()) {
assert (CD->isUsed());
assert(CD->isUsed() && "Sema doesn't consider constructor as used.");
DeferredDeclsToEmit.push_back(D);
}
} else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) {
if (DD->isImplicit()) {
assert (DD->isUsed());
assert(DD->isUsed() && "Sema doesn't consider destructor as used.");
DeferredDeclsToEmit.push_back(D);
}
} else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
if (MD->isCopyAssignment() && MD->isImplicit()) {
assert (MD->isUsed());
assert(MD->isUsed() && "Sema doesn't consider CopyAssignment as used.");
DeferredDeclsToEmit.push_back(D);
}
}
@ -817,6 +862,13 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
// Lookup the entry, lazily creating it if necessary.
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
if (Entry) {
if (WeakRefReferences.count(Entry)) {
if (D && !D->hasAttr<WeakAttr>())
Entry->setLinkage(llvm::Function::ExternalLinkage);
WeakRefReferences.erase(Entry);
}
if (Entry->getType() == Ty)
return Entry;
@ -1203,7 +1255,7 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
const llvm::FunctionType *Ty = getTypes().GetFunctionType(GD);
getMangleContext().mangleInitDiscriminator();
// Get or create the prototype for the function.
llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);

View File

@ -29,6 +29,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ValueHandle.h"
#include <list>
@ -117,6 +118,11 @@ class CodeGenModule : public BlockModule {
/// pointer lookups instead of full string lookups.
llvm::DenseMap<const char*, llvm::GlobalValue*> GlobalDeclMap;
// WeakRefReferences - A set of references that have only been seen via
// a weakref so far. This is used to remove the weak of the reference if we ever
// see a direct reference or a definition.
llvm::SmallPtrSet<llvm::GlobalValue*, 10> WeakRefReferences;
/// \brief Contains the strings used for mangled names.
///
/// FIXME: Eventually, this should map from the semantic/canonical
@ -198,6 +204,7 @@ class CodeGenModule : public BlockModule {
const llvm::TargetData &getTargetData() const { return TheTargetData; }
llvm::LLVMContext &getLLVMContext() { return VMContext; }
const TargetCodeGenInfo &getTargetCodeGenInfo() const;
bool isTargetDarwin() const;
/// getDeclVisibilityMode - Compute the visibility of the decl \arg D.
LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const;
@ -243,6 +250,9 @@ class CodeGenModule : public BlockModule {
void BuildThunksForVirtual(GlobalDecl GD);
void BuildThunksForVirtualRecursive(GlobalDecl GD, GlobalDecl BaseOGD);
/// GetWeakRefReference - Get a reference to the target of VD.
llvm::Constant *GetWeakRefReference(const ValueDecl *VD);
/// BuildThunk - Build a thunk for the given method.
llvm::Constant *BuildThunk(GlobalDecl GD, bool Extern,
const ThunkAdjustment &ThisAdjustment);

View File

@ -37,7 +37,19 @@ using namespace clang;
using namespace CodeGen;
namespace {
static const DeclContext *GetLocalClassFunctionDeclContext(
const DeclContext *DC) {
if (isa<CXXRecordDecl>(DC)) {
while (!DC->isNamespace() && !DC->isTranslationUnit() &&
!isa<FunctionDecl>(DC))
DC = DC->getParent();
if (isa<FunctionDecl>(DC))
return DC;
}
return 0;
}
static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) {
assert((isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) &&
"Passed in decl is not a ctor or dtor!");
@ -61,7 +73,7 @@ class CXXNameMangler {
const CXXMethodDecl *Structor;
unsigned StructorType;
llvm::DenseMap<uintptr_t, unsigned> Substitutions;
ASTContext &getASTContext() const { return Context.getASTContext(); }
@ -128,11 +140,12 @@ class CXXNameMangler {
void mangleUnscopedTemplateName(const TemplateDecl *ND);
void mangleSourceName(const IdentifierInfo *II);
void mangleLocalName(const NamedDecl *ND);
void mangleNestedName(const NamedDecl *ND, const DeclContext *DC);
void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
bool NoFunction=false);
void mangleNestedName(const TemplateDecl *TD,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs);
void manglePrefix(const DeclContext *DC);
void manglePrefix(const DeclContext *DC, bool NoFunction=false);
void mangleTemplatePrefix(const TemplateDecl *ND);
void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
void mangleQualifiers(Qualifiers Quals);
@ -342,7 +355,12 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
// ::= <local-name>
//
const DeclContext *DC = ND->getDeclContext();
if (GetLocalClassFunctionDeclContext(DC)) {
mangleLocalName(ND);
return;
}
// If this is an extern variable declared locally, the relevant DeclContext
// is that of the containing namespace, or the translation unit.
if (isa<FunctionDecl>(DC) && ND->hasLinkage())
@ -603,7 +621,8 @@ void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
}
void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
const DeclContext *DC) {
const DeclContext *DC,
bool NoFunction) {
// <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
// ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
@ -616,8 +635,9 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleTemplatePrefix(TD);
mangleTemplateArgs(*TemplateArgs);
} else {
manglePrefix(DC);
}
else {
manglePrefix(DC, NoFunction);
mangleUnqualifiedName(ND);
}
@ -640,18 +660,35 @@ void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
// := Z <function encoding> E s [<discriminator>]
// <discriminator> := _ <non-negative number>
const DeclContext *DC = ND->getDeclContext();
Out << 'Z';
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ND->getDeclContext()))
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
mangleObjCMethodName(MD);
else if (const DeclContext *CDC = GetLocalClassFunctionDeclContext(DC)) {
mangleFunctionEncoding(cast<FunctionDecl>(CDC));
Out << 'E';
mangleNestedName(ND, DC, true /*NoFunction*/);
// FIXME. This still does not cover all cases.
unsigned disc;
if (Context.getNextDiscriminator(ND, disc)) {
if (disc < 10)
Out << '_' << disc;
else
Out << "__" << disc << '_';
}
return;
}
else
mangleFunctionEncoding(cast<FunctionDecl>(ND->getDeclContext()));
mangleFunctionEncoding(cast<FunctionDecl>(DC));
Out << 'E';
mangleUnqualifiedName(ND);
}
void CXXNameMangler::manglePrefix(const DeclContext *DC) {
void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
// <prefix> ::= <prefix> <unqualified-name>
// ::= <template-prefix> <template-args>
// ::= <template-param>
@ -672,8 +709,11 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC) {
if (const TemplateDecl *TD = isTemplate(cast<NamedDecl>(DC), TemplateArgs)) {
mangleTemplatePrefix(TD);
mangleTemplateArgs(*TemplateArgs);
} else {
manglePrefix(DC->getParent());
}
else if(NoFunction && isa<FunctionDecl>(DC))
return;
else {
manglePrefix(DC->getParent(), NoFunction);
mangleUnqualifiedName(cast<NamedDecl>(DC));
}

View File

@ -44,7 +44,9 @@ class MangleContext {
ASTContext &Context;
llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
unsigned Discriminator;
llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
public:
explicit MangleContext(ASTContext &Context)
: Context(Context) { }
@ -85,7 +87,20 @@ class MangleContext {
llvm::SmallVectorImpl<char> &);
void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
llvm::SmallVectorImpl<char> &);
void mangleInitDiscriminator() {
Discriminator = 0;
}
bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
unsigned &discriminator = Uniquifier[ND];
if (!discriminator)
discriminator = ++Discriminator;
if (discriminator == 1)
return false;
disc = discriminator-2;
return true;
}
/// @}
};

View File

@ -328,6 +328,16 @@ class X86_32TargetCodeGenInfo : public TargetCodeGenInfo {
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const;
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
// Darwin uses different dwarf register numbers for EH.
if (CGM.isTargetDarwin()) return 5;
return 4;
}
bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const;
};
}
@ -568,6 +578,51 @@ void X86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
}
}
bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable(
CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const {
CodeGen::CGBuilderTy &Builder = CGF.Builder;
llvm::LLVMContext &Context = CGF.getLLVMContext();
const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
// 0-7 are the eight integer registers; the order is different
// on Darwin (for EH), but the range is the same.
// 8 is %eip.
for (unsigned I = 0, E = 9; I != E; ++I) {
llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
Builder.CreateStore(Four8, Slot);
}
if (CGF.CGM.isTargetDarwin()) {
// 12-16 are st(0..4). Not sure why we stop at 4.
// These have size 16, which is sizeof(long double) on
// platforms with 8-byte alignment for that type.
llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
for (unsigned I = 12, E = 17; I != E; ++I) {
llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
Builder.CreateStore(Sixteen8, Slot);
}
} else {
// 9 is %eflags, which doesn't get a size on Darwin for some
// reason.
Builder.CreateStore(Four8, Builder.CreateConstInBoundsGEP1_32(Address, 9));
// 11-16 are st(0..5). Not sure why we stop at 5.
// These have size 12, which is sizeof(long double) on
// platforms with 4-byte alignment for that type.
llvm::Value *Twelve8 = llvm::ConstantInt::get(i8, 12);
for (unsigned I = 11, E = 17; I != E; ++I) {
llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
Builder.CreateStore(Twelve8, Slot);
}
}
return false;
}
namespace {
/// X86_64ABIInfo - The X86_64 ABI information.
class X86_64ABIInfo : public ABIInfo {
@ -656,6 +711,28 @@ class X86_64ABIInfo : public ABIInfo {
class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {
public:
X86_64TargetCodeGenInfo():TargetCodeGenInfo(new X86_64ABIInfo()) {}
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
return 7;
}
bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const {
CodeGen::CGBuilderTy &Builder = CGF.Builder;
llvm::LLVMContext &Context = CGF.getLLVMContext();
const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
// 0-16 are the 16 integer registers.
// 17 is %rip.
for (unsigned I = 0, E = 17; I != E; ++I) {
llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
Builder.CreateStore(Eight8, Slot);
}
return false;
}
};
}
@ -1559,6 +1636,10 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
public:
ARMTargetCodeGenInfo(ARMABIInfo::ABIKind K)
:TargetCodeGenInfo(new ARMABIInfo(K)) {}
int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
return 13;
}
};
}

View File

@ -56,6 +56,23 @@ namespace clang {
/// through such registers.
virtual bool extendPointerWithSExt() const { return false; }
/// Determines the DWARF register number for the stack pointer, for
/// exception-handling purposes. Implements __builtin_dwarf_sp_column.
///
/// Returns -1 if the operation is unsupported by this target.
virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
return -1;
}
/// Initializes the given DWARF EH register-size table, a char*.
/// Implements __builtin_init_dwarf_reg_size_table.
///
/// Returns true if the operation is unsupported by this target.
virtual bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const {
return true;
}
/// Performs the code-generation required to convert a return
/// address as stored by the system into the actual address of the
/// next instruction that will be executed.

View File

@ -1145,6 +1145,10 @@ const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
llvm::PrettyStackTraceString CrashInfo("Constructing host");
llvm::Triple Triple(TripleStr);
// TCE is an osless target
if (Triple.getArchName() == "tce")
return createTCEHostInfo(*this, Triple);
switch (Triple.getOS()) {
case llvm::Triple::AuroraUX:
return createAuroraUXHostInfo(*this, Triple);

View File

@ -157,6 +157,46 @@ ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args,
return TC;
}
// TCE Host Info
/// TCEHostInfo - TCE host information implementation (see http://tce.cs.tut.fi)
class TCEHostInfo : public HostInfo {
public:
TCEHostInfo(const Driver &D, const llvm::Triple &Triple);
~TCEHostInfo() {};
virtual bool useDriverDriver() const;
virtual types::ID lookupTypeForExtension(const char *Ext) const {
types::ID Ty = types::lookupTypeForExtension(Ext);
if (Ty == types::TY_PP_Asm)
return types::TY_Asm;
return Ty;
}
virtual ToolChain *CreateToolChain(const ArgList &Args,
const char *ArchName) const;
};
TCEHostInfo::TCEHostInfo(const Driver &D, const llvm::Triple& Triple)
: HostInfo(D, Triple) {
}
bool TCEHostInfo::useDriverDriver() const {
return false;
}
ToolChain *TCEHostInfo::CreateToolChain(const ArgList &Args,
const char *ArchName) const {
llvm::Triple TCTriple(getTriple());
// TCTriple.setArchName(ArchName);
return new toolchains::TCEToolChain(*this, TCTriple);
}
// Unknown Host Info
/// UnknownHostInfo - Generic host information to use for unknown hosts.
@ -535,6 +575,12 @@ clang::driver::createLinuxHostInfo(const Driver &D,
return new LinuxHostInfo(D, Triple);
}
const HostInfo *
clang::driver::createTCEHostInfo(const Driver &D,
const llvm::Triple& Triple) {
return new TCEHostInfo(D, Triple);
}
const HostInfo *
clang::driver::createUnknownHostInfo(const Driver &D,
const llvm::Triple& Triple) {

View File

@ -728,6 +728,66 @@ DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args,
return new DerivedArgList(Args, true);
}
/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
/// Currently does not support anything else but compilation.
TCEToolChain::TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple)
: ToolChain(Host, Triple) {
// Path mangling to find libexec
std::string Path(getDriver().Dir);
Path += "/../libexec";
getProgramPaths().push_back(Path);
}
TCEToolChain::~TCEToolChain() {
for (llvm::DenseMap<unsigned, Tool*>::iterator
it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
delete it->second;
}
bool TCEToolChain::IsMathErrnoDefault() const {
return true;
}
bool TCEToolChain::IsUnwindTablesDefault() const {
return false;
}
const char *TCEToolChain::GetDefaultRelocationModel() const {
return "static";
}
const char *TCEToolChain::GetForcedPicModel() const {
return 0;
}
Tool &TCEToolChain::SelectTool(const Compilation &C,
const JobAction &JA) const {
Action::ActionClass Key;
Key = Action::AnalyzeJobClass;
Tool *&T = Tools[Key];
if (!T) {
switch (Key) {
case Action::PreprocessJobClass:
T = new tools::gcc::Preprocess(*this); break;
case Action::AnalyzeJobClass:
T = new tools::Clang(*this); break;
default:
assert(false && "Unsupported action for TCE target.");
}
}
return *T;
}
DerivedArgList *TCEToolChain::TranslateArgs(InputArgList &Args,
const char *BoundArch) const {
return new DerivedArgList(Args, true);
}
/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)

View File

@ -267,6 +267,26 @@ class VISIBILITY_HIDDEN Linux : public Generic_GCC {
};
/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
class VISIBILITY_HIDDEN TCEToolChain : public ToolChain {
public:
TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple);
~TCEToolChain();
virtual DerivedArgList *TranslateArgs(InputArgList &Args,
const char *BoundArch) const;
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
bool IsMathErrnoDefault() const;
bool IsUnwindTablesDefault() const;
const char* GetDefaultRelocationModel() const;
const char* GetForcedPicModel() const;
private:
mutable llvm::DenseMap<unsigned, Tool*> Tools;
};
} // end namespace toolchains
} // end namespace driver
} // end namespace clang

View File

@ -36,9 +36,10 @@
using namespace clang;
ASTUnit::ASTUnit(bool _MainFileIsAST)
: MainFileIsAST(_MainFileIsAST) {
: MainFileIsAST(_MainFileIsAST), ConcurrencyCheckValue(CheckUnlocked) {
}
ASTUnit::~ASTUnit() {
ConcurrencyCheckValue = CheckLocked;
for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
TemporaryFiles[I].eraseFromDisk();
}

View File

@ -184,9 +184,7 @@ class PTHWriter {
/// Emit a token to the PTH file.
void EmitToken(const Token& T);
void Emit8(uint32_t V) {
Out << (unsigned char)(V);
}
void Emit8(uint32_t V) { ::Emit8(Out, V); }
void Emit16(uint32_t V) { ::Emit16(Out, V); }

View File

@ -566,6 +566,17 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &tripl
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4",
"i686-pc-linux-gnu", "", "", triple);
// Gentoo amd64 gcc 4.3.2
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.2/include/g++-v4",
"x86_64-pc-linux-gnu", "", "", triple);
// Gentoo amd64 gcc 4.4.3
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/include/g++-v4",
"x86_64-pc-linux-gnu", "32", "", triple);
break;
case llvm::Triple::FreeBSD:
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple);

View File

@ -4266,6 +4266,17 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
// Insert declaration for the function in which block literal is used.
if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
bool RewriteSC = (GlobalVarDecl &&
!Blocks.empty() &&
GlobalVarDecl->getStorageClass() == VarDecl::Static &&
GlobalVarDecl->getType().getCVRQualifiers());
if (RewriteSC) {
std::string SC(" void __");
SC += GlobalVarDecl->getNameAsString();
SC += "() {}";
InsertText(FunLocStart, SC);
}
// Insert closures that were part of the function.
for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
CollectBlockDeclRefInfo(Blocks[i]);
@ -4311,6 +4322,21 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
BlockByCopyDeclsPtrSet.clear();
ImportedBlockDecls.clear();
}
if (RewriteSC) {
// Must insert any 'const/volatile/static here. Since it has been
// removed as result of rewriting of block literals.
std::string SC;
if (GlobalVarDecl->getStorageClass() == VarDecl::Static)
SC = "static ";
if (GlobalVarDecl->getType().isConstQualified())
SC += "const ";
if (GlobalVarDecl->getType().isVolatileQualified())
SC += "volatile ";
if (GlobalVarDecl->getType().isRestrictQualified())
SC += "restrict ";
InsertText(FunLocStart, SC);
}
Blocks.clear();
InnerDeclRefsCount.clear();
InnerDeclRefs.clear();

130
lib/Headers/smmintrin.h Normal file
View File

@ -0,0 +1,130 @@
/*===---- smmintrin.h - SSE intrinsics -------------------------------------===
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*===-----------------------------------------------------------------------===
*/
#ifndef _SMMINTRIN_H
#define _SMMINTRIN_H
#ifndef __SSE4_1__
#error "SSE4.1 instruction set not enabled"
#else
#include <tmmintrin.h>
/* Type defines. */
typedef double __v2df __attribute__ ((__vector_size__ (16)));
/* SSE4 Rounding macros. */
#define _MM_FROUND_TO_NEAREST_INT 0x00
#define _MM_FROUND_TO_NEG_INF 0x01
#define _MM_FROUND_TO_POS_INF 0x02
#define _MM_FROUND_TO_ZERO 0x03
#define _MM_FROUND_CUR_DIRECTION 0x04
#define _MM_FROUND_RAISE_EXC 0x00
#define _MM_FROUND_NO_EXC 0x08
#define _MM_FROUND_NINT (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_NEAREST_INT)
#define _MM_FROUND_FLOOR (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_NEG_INF)
#define _MM_FROUND_CEIL (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_POS_INF)
#define _MM_FROUND_TRUNC (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_ZERO)
#define _MM_FROUND_RINT (_MM_FROUND_RAISE_EXC | _MM_FROUND_CUR_DIRECTION)
#define _MM_FROUND_NEARBYINT (_MM_FROUND_RAISE_EXC | _MM_FROUND_CUR_DIRECTION)
#define _mm_ceil_ps(X) _mm_round_ps((X), _MM_FROUND_CEIL)
#define _mm_ceil_pd(X) _mm_round_pd((X), _MM_FROUND_CEIL)
#define _mm_ceil_ss(X, Y) _mm_round_ss((X), (Y), _MM_FROUND_CEIL)
#define _mm_ceil_sd(X, Y) _mm_round_sd((X), (Y), _MM_FROUND_CEIL)
#define _mm_floor_ps(X) _mm_round_ps((X), _MM_FROUND_FLOOR)
#define _mm_floor_pd(X) _mm_round_pd((X), _MM_FROUND_FLOOR)
#define _mm_floor_ss(X, Y) _mm_round_ss((X), (Y), _MM_FROUND_FLOOR)
#define _mm_floor_sd(X, Y) _mm_round_sd((X), (Y), _MM_FROUND_FLOOR)
/* SSE4 Rounding Intrinsics. */
static inline __m128 __attribute__((__always_inline__, __nodebug__))
_mm_round_ps (__m128 __V, const int __M)
{
return (__m128) __builtin_ia32_roundps ((__v4sf)__V, __M);
}
static inline __m128 __attribute__((__always_inline__, __nodebug__))
_mm_round_ss (__m128 __V1, __m128 __V2, const int __M)
{
return (__m128) __builtin_ia32_roundss ((__v4sf)__V1, (__v4sf)__V2, __M);
}
static inline __m128d __attribute__((__always_inline__, __nodebug__))
_mm_round_pd (__m128d __V, const int __M)
{
return (__m128d) __builtin_ia32_roundpd ((__v2df)__V, __M);
}
static inline __m128d __attribute__((__always_inline__, __nodebug__))
_mm_round_sd(__m128d __V1, __m128d __V2, const int __M)
{
return (__m128d) __builtin_ia32_roundsd ((__v2df)__V1, (__v2df)__V2, __M);
}
/* SSE4 Packed Blending Intrinsics. */
static inline __m128d __attribute__((__always_inline__, __nodebug__))
_mm_blend_pd (__m128d __V1, __m128d __V2, const int __M)
{
return (__m128d) __builtin_ia32_blendpd ((__v2df)__V1, (__v2df)__V2, __M);
}
static inline __m128 __attribute__((__always_inline__, __nodebug__))
_mm_blend_ps (__m128 __V1, __m128 __V2, const int __M)
{
return (__m128) __builtin_ia32_blendps ((__v4sf)__V1, (__v4sf)__V2, __M);
}
static inline __m128d __attribute__((__always_inline__, __nodebug__))
_mm_blendv_pd (__m128d __V1, __m128d __V2, __m128d __M)
{
return (__m128d) __builtin_ia32_blendvpd ((__v2df)__V1, (__v2df)__V2,
(__v2df)__M);
}
static inline __m128 __attribute__((__always_inline__, __nodebug__))
_mm_blendv_ps (__m128 __V1, __m128 __V2, __m128 __M)
{
return (__m128) __builtin_ia32_blendvps ((__v4sf)__V1, (__v4sf)__V2,
(__v4sf)__M);
}
static inline __m128i __attribute__((__always_inline__, __nodebug__))
_mm_blendv_epi8 (__m128i __V1, __m128i __V2, __m128i __M)
{
return (__m128i) __builtin_ia32_pblendvb128 ((__v16qi)__V1, (__v16qi)__V2,
(__v16qi)__M);
}
static inline __m128i __attribute__((__always_inline__, __nodebug__))
_mm_blend_epi16 (__m128i __V1, __m128i __V2, const int __M)
{
return (__m128i) __builtin_ia32_pblendw128 ((__v8hi)__V1, (__v8hi)__V2, __M);
}
#endif /* __SSE4_1__ */
#endif /* _SMMINTRIN_H */

View File

@ -505,6 +505,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("attribute_cf_returns_retained", true)
.Case("attribute_ns_returns_not_retained", true)
.Case("attribute_ns_returns_retained", true)
.Case("attribute_objc_ivar_unused", true)
.Default(false);
}

View File

@ -1097,12 +1097,16 @@ class Sema : public Action {
ImplicitConversionSequence
TryObjectArgumentInitialization(QualType FromType, CXXMethodDecl *Method,
CXXRecordDecl *ActingContext);
bool PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method);
bool PerformObjectArgumentInitialization(Expr *&From,
NestedNameSpecifier *Qualifier,
CXXMethodDecl *Method);
ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From);
bool PerformContextuallyConvertToBool(Expr *&From);
bool PerformObjectMemberConversion(Expr *&From, NamedDecl *Member);
bool PerformObjectMemberConversion(Expr *&From,
NestedNameSpecifier *Qualifier,
NamedDecl *Member);
// Members have to be NamespaceDecl* or TranslationUnitDecl*.
// TODO: make this is a typesafe union.

View File

@ -5212,14 +5212,35 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
AbstractVariableType))
Invalid = true;
// FIXME: Need to test for ability to copy-construct and destroy the
// exception variable.
// FIXME: Need to check for abstract classes.
VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc,
Name, ExDeclType, TInfo, VarDecl::None);
if (!Invalid) {
if (const RecordType *RecordTy = ExDeclType->getAs<RecordType>()) {
// C++ [except.handle]p16:
// The object declared in an exception-declaration or, if the
// exception-declaration does not specify a name, a temporary (12.2) is
// copy-initialized (8.5) from the exception object. [...]
// The object is destroyed when the handler exits, after the destruction
// of any automatic objects initialized within the handler.
//
// We just pretend to initialize the object with itself, then make sure
// it can be destroyed later.
InitializedEntity Entity = InitializedEntity::InitializeVariable(ExDecl);
Expr *ExDeclRef = DeclRefExpr::Create(Context, 0, SourceRange(), ExDecl,
Loc, ExDeclType, 0);
InitializationKind Kind = InitializationKind::CreateCopy(Loc,
SourceLocation());
InitializationSequence InitSeq(*this, Entity, Kind, &ExDeclRef, 1);
OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
MultiExprArg(*this, (void**)&ExDeclRef, 1));
if (Result.isInvalid())
Invalid = true;
else
FinalizeVarWithDestructor(ExDecl, RecordTy);
}
}
if (Invalid)
ExDecl->setInvalidDecl();

View File

@ -635,7 +635,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
MemberType = Context.getQualifiedType(MemberType, NewQuals);
MarkDeclarationReferenced(Loc, *FI);
PerformObjectMemberConversion(Result, *FI);
PerformObjectMemberConversion(Result, /*FIXME:Qualifier=*/0, *FI);
// FIXME: Might this end up being a qualified name?
Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI,
OpLoc, MemberType);
@ -1357,29 +1357,111 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
/// \brief Cast member's object to its own class if necessary.
bool
Sema::PerformObjectMemberConversion(Expr *&From, NamedDecl *Member) {
if (FieldDecl *FD = dyn_cast<FieldDecl>(Member))
if (CXXRecordDecl *RD =
dyn_cast<CXXRecordDecl>(FD->getDeclContext())) {
QualType DestType =
Context.getCanonicalType(Context.getTypeDeclType(RD));
if (DestType->isDependentType() || From->getType()->isDependentType())
return false;
QualType FromRecordType = From->getType();
QualType DestRecordType = DestType;
if (FromRecordType->getAs<PointerType>()) {
DestType = Context.getPointerType(DestType);
FromRecordType = FromRecordType->getPointeeType();
}
if (!Context.hasSameUnqualifiedType(FromRecordType, DestRecordType) &&
CheckDerivedToBaseConversion(FromRecordType,
DestRecordType,
From->getSourceRange().getBegin(),
From->getSourceRange()))
return true;
ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase,
/*isLvalue=*/true);
Sema::PerformObjectMemberConversion(Expr *&From,
NestedNameSpecifier *Qualifier,
NamedDecl *Member) {
CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext());
if (!RD)
return false;
QualType DestRecordType;
QualType DestType;
QualType FromRecordType;
QualType FromType = From->getType();
bool PointerConversions = false;
if (isa<FieldDecl>(Member)) {
DestRecordType = Context.getCanonicalType(Context.getTypeDeclType(RD));
if (FromType->getAs<PointerType>()) {
DestType = Context.getPointerType(DestRecordType);
FromRecordType = FromType->getPointeeType();
PointerConversions = true;
} else {
DestType = DestRecordType;
FromRecordType = FromType;
}
} else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) {
if (Method->isStatic())
return false;
DestType = Method->getThisType(Context);
DestRecordType = DestType->getPointeeType();
if (FromType->getAs<PointerType>()) {
FromRecordType = FromType->getPointeeType();
PointerConversions = true;
} else {
FromRecordType = FromType;
DestType = DestRecordType;
}
} else {
// No conversion necessary.
return false;
}
if (DestType->isDependentType() || FromType->isDependentType())
return false;
// If the unqualified types are the same, no conversion is necessary.
if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
return false;
// C++ [class.member.lookup]p8:
// [...] Ambiguities can often be resolved by qualifying a name with its
// class name.
//
// If the member was a qualified name and the qualified referred to a
// specific base subobject type, we'll cast to that intermediate type
// first and then to the object in which the member is declared. That allows
// one to resolve ambiguities in, e.g., a diamond-shaped hierarchy such as:
//
// class Base { public: int x; };
// class Derived1 : public Base { };
// class Derived2 : public Base { };
// class VeryDerived : public Derived1, public Derived2 { void f(); };
//
// void VeryDerived::f() {
// x = 17; // error: ambiguous base subobjects
// Derived1::x = 17; // okay, pick the Base subobject of Derived1
// }
QualType IntermediateRecordType;
QualType IntermediateType;
if (Qualifier) {
if (const RecordType *IntermediateRecord
= Qualifier->getAsType()->getAs<RecordType>()) {
IntermediateRecordType = QualType(IntermediateRecord, 0);
IntermediateType = IntermediateRecordType;
if (PointerConversions)
IntermediateType = Context.getPointerType(IntermediateType);
}
}
if (!IntermediateType.isNull() &&
IsDerivedFrom(FromRecordType, IntermediateRecordType) &&
IsDerivedFrom(IntermediateRecordType, DestRecordType)) {
if (CheckDerivedToBaseConversion(FromRecordType, IntermediateRecordType,
From->getSourceRange().getBegin(),
From->getSourceRange()) ||
CheckDerivedToBaseConversion(IntermediateRecordType, DestRecordType,
From->getSourceRange().getBegin(),
From->getSourceRange()))
return true;
ImpCastExprToType(From, IntermediateType, CastExpr::CK_DerivedToBase,
/*isLvalue=*/!PointerConversions);
ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase,
/*isLvalue=*/!PointerConversions);
return false;
}
if (CheckDerivedToBaseConversion(FromRecordType,
DestRecordType,
From->getSourceRange().getBegin(),
From->getSourceRange()))
return true;
ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase,
/*isLvalue=*/true);
return false;
}
@ -1609,7 +1691,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
return ExprError();
}
if (VD->getType()->isArrayType()) {
if (VD->getType()->isArrayType() && !VD->hasAttr<BlocksAttr>()) {
Diag(Loc, diag::err_ref_array_type);
Diag(D->getLocation(), diag::note_declared_at);
return ExprError();
@ -2666,7 +2748,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
}
MarkDeclarationReferenced(MemberLoc, FD);
if (PerformObjectMemberConversion(BaseExpr, FD))
if (PerformObjectMemberConversion(BaseExpr, Qualifier, FD))
return ExprError();
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
FD, MemberLoc, MemberType));
@ -6651,7 +6733,7 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
Res = BuildAnonymousStructUnionMemberReference(
OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs<Expr>();
} else {
PerformObjectMemberConversion(Res, MemberDecl);
PerformObjectMemberConversion(Res, /*Qualifier=*/0, MemberDecl);
// MemberDecl->getType() doesn't get the right qualifiers, but it
// doesn't matter here.
Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd,

View File

@ -2881,7 +2881,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp,
CXXMethodDecl *Method) {
if (PerformObjectArgumentInitialization(Exp, Method))
if (PerformObjectArgumentInitialization(Exp, /*Qualifier=*/0, Method))
assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?");
MemberExpr *ME =

View File

@ -3365,7 +3365,8 @@ InitializationSequence::Perform(Sema &S,
// FIXME: Should we move this initialization into a separate
// derived-to-base conversion? I believe the answer is "no", because
// we don't want to turn off access control here for c-style casts.
if (S.PerformObjectArgumentInitialization(CurInitExpr, Conversion))
if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0,
Conversion))
return S.ExprError();
// Do a little dance to make sure that CurInit has the proper

View File

@ -1282,8 +1282,8 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
QualType FromPointeeType = FromPtrType->getPointeeType(),
ToPointeeType = ToPtrType->getPointeeType();
if (FromPointeeType->isRecordType() &&
ToPointeeType->isRecordType()) {
if (FromPointeeType->isRecordType() && ToPointeeType->isRecordType() &&
!Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) {
// We must have a derived-to-base conversion. Check an
// ambiguous or inaccessible conversion.
if (CheckDerivedToBaseConversion(FromPointeeType, ToPointeeType,
@ -2304,7 +2304,9 @@ Sema::TryObjectArgumentInitialization(QualType OrigFromType,
/// the implicit object parameter for the given Method with the given
/// expression.
bool
Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) {
Sema::PerformObjectArgumentInitialization(Expr *&From,
NestedNameSpecifier *Qualifier,
CXXMethodDecl *Method) {
QualType FromRecordType, DestType;
QualType ImplicitParamRecordType =
Method->getThisType(Context)->getAs<PointerType>()->getPointeeType();
@ -2327,15 +2329,12 @@ Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) {
diag::err_implicit_object_parameter_init)
<< ImplicitParamRecordType << FromRecordType << From->getSourceRange();
if (ICS.Standard.Second == ICK_Derived_To_Base &&
CheckDerivedToBaseConversion(FromRecordType,
ImplicitParamRecordType,
From->getSourceRange().getBegin(),
From->getSourceRange()))
return true;
if (ICS.Standard.Second == ICK_Derived_To_Base)
return PerformObjectMemberConversion(From, Qualifier, Method);
ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase,
/*isLvalue=*/true);
if (!Context.hasSameType(From->getType(), DestType))
ImpCastExprToType(From, DestType, CastExpr::CK_NoOp,
/*isLvalue=*/!From->getType()->getAs<PointerType>());
return false;
}
@ -5545,7 +5544,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
CheckMemberOperatorAccess(OpLoc, Args[0], Method, Best->getAccess());
if (PerformObjectArgumentInitialization(Input, Method))
if (PerformObjectArgumentInitialization(Input, /*Qualifier=*/0, Method))
return ExprError();
} else {
// Convert the arguments.
@ -5738,7 +5737,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (Arg1.isInvalid())
return ExprError();
if (PerformObjectArgumentInitialization(Args[0], Method))
if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
Method))
return ExprError();
Args[1] = RHS = Arg1.takeAs<Expr>();
@ -5904,7 +5904,8 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// Convert the arguments.
CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
if (PerformObjectArgumentInitialization(Args[0], Method))
if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
Method))
return ExprError();
// Convert the arguments.
@ -6009,12 +6010,15 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
MemberExpr *MemExpr;
CXXMethodDecl *Method = 0;
NestedNameSpecifier *Qualifier = 0;
if (isa<MemberExpr>(NakedMemExpr)) {
MemExpr = cast<MemberExpr>(NakedMemExpr);
Method = cast<CXXMethodDecl>(MemExpr->getMemberDecl());
Qualifier = MemExpr->getQualifier();
} else {
UnresolvedMemberExpr *UnresExpr = cast<UnresolvedMemberExpr>(NakedMemExpr);
Qualifier = UnresExpr->getQualifier();
QualType ObjectType = UnresExpr->getBaseType();
// Add overload candidates
@ -6113,7 +6117,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
// Convert the object argument (for a non-static member function call).
Expr *ObjectArg = MemExpr->getBase();
if (!Method->isStatic() &&
PerformObjectArgumentInitialization(ObjectArg, Method))
PerformObjectArgumentInitialization(ObjectArg, Qualifier, Method))
return ExprError();
MemExpr->setBase(ObjectArg);
@ -6333,7 +6337,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
bool IsError = false;
// Initialize the implicit object parameter.
IsError |= PerformObjectArgumentInitialization(Object, Method);
IsError |= PerformObjectArgumentInitialization(Object, /*Qualifier=*/0,
Method);
TheCall->setArg(0, Object);
@ -6458,7 +6463,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
// Convert the object parameter.
CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
if (PerformObjectArgumentInitialization(Base, Method))
if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0, Method))
return ExprError();
// No concerns about early exits now.

View File

@ -1034,7 +1034,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>();
T = Context.getObjCObjectPointerType(T,
(ObjCProtocolDecl **)OIT->qual_begin(),
OIT->getNumProtocols());
OIT->getNumProtocols(),
DeclType.Ptr.TypeQuals);
break;
}
T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name);

View File

@ -969,7 +969,7 @@ class TreeTransform {
assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Expr *BaseExpr = Base.takeAs<Expr>();
if (getSema().PerformObjectMemberConversion(BaseExpr, Member))
if (getSema().PerformObjectMemberConversion(BaseExpr, Qualifier, Member))
return getSema().ExprError();
MemberExpr *ME =

15
test/Analysis/inline3.c Normal file
View File

@ -0,0 +1,15 @@
// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
// Test when entering f1(), we set the right AnalysisContext to Environment.
// Otherwise, block-level expr '1 && a' would not be block-level.
int a;
void f1() {
if (1 && a)
return;
}
void f2() {
f1();
}

View File

@ -0,0 +1,63 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// FIXME: Access control checks
namespace PR5820 {
// also <rdar://problem/7535045>
struct Base {
void Foo();
int Member;
};
struct D1 : public Base {};
struct D2 : public Base {};
struct Derived : public D1, public D2 {
void Inner();
};
void Test() {
Derived d;
d.D1::Foo();
d.D1::Member = 17;
}
void Derived::Inner() {
D1::Foo();
D1::Member = 42;
this->D1::Foo();
this->D1::Member = 42;
}
}
template<typename T>
struct BaseT {
void Foo(); // expected-note{{found by ambiguous name lookup}}
int Member;
};
template<typename T> struct Derived1T : BaseT<T> { };
template<typename T> struct Derived2T : BaseT<T> { };
template<typename T>
struct DerivedT : public Derived1T<T>, public Derived2T<T> {
void Inner();
};
template<typename T>
void DerivedT<T>::Inner() {
Derived1T<T>::Foo();
Derived2T<T>::Member = 42;
this->Derived1T<T>::Foo();
this->Derived2T<T>::Member = 42;
this->Foo(); // expected-error{{non-static member 'Foo' found in multiple base-class subobjects of type 'BaseT<int>'}}
}
template<typename T>
void Test(DerivedT<T> d) {
d.template Derived1T<T>::Foo();
d.template Derived2T<T>::Member = 17;
d.Inner(); // expected-note{{in instantiation}}
}
template void Test(DerivedT<int>);

View File

@ -0,0 +1,40 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// The object declared in an exception-declaration or, if the
// exception-declaration does not specify a name, a temporary (12.2)
// is copy-initialized (8.5) from the exception object.
//
template<typename T>
class X {
T* ptr;
public:
X(const X<T> &) {
int *ip = 0;
ptr = ip; // expected-error{{incompatible type assigning 'int *', expected 'float *'}}
}
~X() {
float *fp = 0;
ptr = fp; // expected-error{{incompatible type assigning 'float *', expected 'int *'}}
}
};
void f() {
try {
} catch (X<float>) { // expected-note{{instantiation}}
// copy constructor
} catch (X<int> xi) { // expected-note{{instantiation}}
// destructor
}
}
struct Abstract {
virtual void f() = 0; // expected-note{{pure virtual}}
};
void g() {
try {
} catch (Abstract) { // expected-error{{variable type 'Abstract' is an abstract class}}
}
}

View File

@ -1,10 +0,0 @@
// RUN: %clang_cc1 -emit-llvm %s -o %t -triple i386-pc-linux-gnu -O2
// RUN: not grep "load" %t
// <rdar://problem/6841383>
int cpuid(unsigned data) {
int a, b;
asm("xyz" :"=a"(a), "=d"(b) : "a"(data));
return a + b;
}

View File

@ -1,18 +0,0 @@
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o %t
// RUN: grep "load i8\*\*\* %p.addr" %t | count 1
// XFAIL: *
// PR3800
void f(void **p)
{
__asm__ volatile("" :"+m"(*p));
}
#if 0
// FIXME: Once this works again, we must verify that the code below behaves as expected
// See PR4677.
void f() {
unsigned _data = 42;
__asm__("bswap %0":"+r"(_data));
}
#endif

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o %t
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
void t1(int len) {
__asm__ volatile("" : "=&r"(len), "+&r"(len));
}
@ -28,14 +28,16 @@ void t6(void) {
__asm__ volatile("" : : "i" (t6));
}
// RUN: grep "T7 NAMED: \$1" %t
void t7(int a) {
__asm__ volatile("T7 NAMED: %[input]" : "+r"(a): [input] "i" (4));
// CHECK: @t7(i32
// CHECK: T7 NAMED: $1
}
// RUN: grep "T8 NAMED MODIFIER: \${0:c}" %t
void t8() {
__asm__ volatile("T8 NAMED MODIFIER: %c[input]" :: [input] "i" (4));
// CHECK: @t8()
// CHECK: T8 NAMED MODIFIER: ${0:c}
}
// PR3682
@ -45,9 +47,11 @@ unsigned t9(unsigned int a) {
}
// PR3908
// RUN: grep "PR3908 \$1 \$3 \$2 \$0" %t
void t10(int r) {
__asm__("PR3908 %[lf] %[xx] %[li] %[r]" : [r] "+r" (r) : [lf] "mx" (0), [li] "mr" (0), [xx] "x" ((double)(0)));
// CHECK: @t10(
// CHECK:PR3908 $1 $3 $2 $0
}
@ -110,3 +114,24 @@ int t16() {
);
return 0;
}
// PR6475
void t17() {
int i;
__asm__ ( "nop": "=m"(i));
// CHECK: @t17()
// CHECK: call void asm "nop", "=*m,
}
// <rdar://problem/6841383>
int t18(unsigned data) {
int a, b;
asm("xyz" :"=a"(a), "=d"(b) : "a"(data));
return a + b;
// CHECK: t18(i32
// CHECK: = call {{.*}}asm "xyz"
// CHECK-NEXT: extractvalue
// CHECK-NEXT: extractvalue
}

View File

@ -0,0 +1,62 @@
// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu -o %t %s
// RUN: FileCheck --input-file=%t %s
// CHECK: declare extern_weak void @test1_f()
void test1_f(void);
static void test1_g(void) __attribute__((weakref("test1_f")));
void test1_h(void) {
test1_g();
}
// CHECK: define void @test2_f()
void test2_f(void) {}
static void test2_g(void) __attribute__((weakref("test2_f")));
void test2_h(void) {
test2_g();
}
// CHECK: declare void @test3_f()
void test3_f(void);
static void test3_g(void) __attribute__((weakref("test3_f")));
void test3_foo(void) {
test3_f();
}
void test3_h(void) {
test3_g();
}
// CHECK: define void @test4_f()
void test4_f(void);
static void test4_g(void) __attribute__((weakref("test4_f")));
void test4_h(void) {
test4_g();
}
void test4_f(void) {}
// CHECK: declare void @test5_f()
void test5_f(void);
static void test5_g(void) __attribute__((weakref("test5_f")));
void test5_h(void) {
test5_g();
}
void test5_foo(void) {
test5_f();
}
// CHECK: declare extern_weak void @test6_f()
void test6_f(void) __attribute__((weak));
static void test6_g(void) __attribute__((weakref("test6_f")));
void test6_h(void) {
test6_g();
}
void test6_foo(void) {
test6_f();
}
// CHECK: declare extern_weak void @test7_f()
void test7_f(void);
static void test7_g(void) __attribute__((weakref("test7_f")));
static void *const test7_zed = (void *) &test7_g;
void* test7_h(void) {
return test7_zed;
}

View File

@ -0,0 +1,54 @@
// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu -o %t %s
// RUN: FileCheck --input-file=%t %s
// CHECK: @test1_f = extern_weak global i32
extern int test1_f;
static int test1_g __attribute__((weakref("test1_f")));
int test1_h(void) {
return test1_g;
}
// CHECK: @test2_f = common global i32 0, align 4
int test2_f;
static int test2_g __attribute__((weakref("test2_f")));
int test2_h(void) {
return test2_g;
}
// CHECK: @test3_f = external global i32
extern int test3_f;
static int test3_g __attribute__((weakref("test3_f")));
int test3_foo(void) {
return test3_f;
}
int test3_h(void) {
return test3_g;
}
// CHECK: @test4_f = common global i32 0, align 4
extern int test4_f;
static int test4_g __attribute__((weakref("test4_f")));
int test4_h(void) {
return test4_g;
}
int test4_f;
// CHECK: @test5_f = external global i32
extern int test5_f;
static int test5_g __attribute__((weakref("test5_f")));
int test5_h(void) {
return test5_g;
}
int test5_foo(void) {
return test5_f;
}
// CHECK: @test6_f = extern_weak global i32
extern int test6_f __attribute__((weak));
static int test6_g __attribute__((weakref("test6_f")));
int test6_h(void) {
return test6_g;
}
int test6_foo(void) {
return test6_f;
}

View File

@ -30,12 +30,6 @@ int t12 __attribute__((section("SECT")));
void __t8() {}
void t9() __attribute__((weak, alias("__t8")));
static void t22(void) __attribute__((weakref("t8")));
// CHECK: @t22 = alias weak void ()* @t8
static void t23(void) __attribute__((weakref, alias("t8")));
// CHECK: @t23 = alias weak void ()* @t8
// CHECK: declare extern_weak i32 @t15()
int __attribute__((weak_import)) t15(void);
int t17() {

106
test/CodeGen/blockstret.c Normal file
View File

@ -0,0 +1,106 @@
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64
// RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32
// X64: internal constant %2 { i8** @_NSConcreteGlobalBlock, i32 1879048192
// X64: store i32 1610612736, i32* %want
// X32: @_NSConcreteGlobalBlock, i32 1879048192, i32 0,
// X32: store i32 1610612736, i32* %want
// rdar://7677537
int printf(const char *, ...);
void *malloc(__SIZE_TYPE__ size);
typedef struct bigbig {
int array[512];
char more[32];
} BigStruct_t;
BigStruct_t (^global)(void) = ^{ return *(BigStruct_t *)malloc(sizeof(struct bigbig)); };
const char * getBlockSignature(void *);
BigStruct_t foo(int param) {
BigStruct_t x;
BigStruct_t (^f)(int) = ^(int param) {
BigStruct_t *result = malloc(sizeof(BigStruct_t));
result->array[23] = param;
return *result;
};
getBlockSignature(f);
return x;
}
enum {
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
BLOCK_HAS_CXX_OBJ = (1 << 26),
BLOCK_IS_GLOBAL = (1 << 28),
BLOCK_USE_STRET = (1 << 29),
BLOCK_HAS_OBJC_TYPE = (1 << 30)
};
struct block_descriptor_big {
unsigned long int reserved;
unsigned long int size;
void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE
void (*dispose)(void *); // conditional on BLOCK_HAS_COPY_DISPOSE
const char *signature; // conditional on BLOCK_HAS_OBJC
const char *layout; // conditional on BLOCK_HAS_OBJC
};
struct block_descriptor_small {
unsigned long int reserved;
unsigned long int size;
const char *signature; // conditional on BLOCK_HAS_OBJC
const char *layout; // conditional on BLOCK_HAS_OBJC
};
struct block_layout_abi { // can't change
void *isa;
int flags;
int reserved;
void (*invoke)(void *, ...);
struct block_descriptor_big *descriptor;
};
const char *getBlockSignature(void *block) {
struct block_layout_abi *layout = (struct block_layout_abi *)block;
if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return 0;
if (layout->flags & BLOCK_HAS_COPY_DISPOSE)
return layout->descriptor->signature;
else
return ((struct block_descriptor_small *)layout->descriptor)->signature;
}
int usesStruct(void *block) {
struct block_layout_abi *layout = (struct block_layout_abi *)block;
int want = BLOCK_HAS_OBJC_TYPE | BLOCK_USE_STRET;
return (layout->flags & want) == want;
}
int main(int argc, char *argv[]) {
printf("desired global flags: %d\n", BLOCK_USE_STRET | BLOCK_IS_GLOBAL | BLOCK_HAS_OBJC_TYPE);
printf("desired stack flags: %d\n", BLOCK_USE_STRET | BLOCK_HAS_OBJC_TYPE);
printf("should be non-zero: %d\n", usesStruct(global));
BigStruct_t x;
BigStruct_t (^local)(int) = ^(int param) {
BigStruct_t *result = (BigStruct_t *)malloc(sizeof(BigStruct_t));
result->array[23] = argc;
return *result;
};
printf("should be non-zero: %d\n", usesStruct(global));
printf("should be non-zero: %d\n", usesStruct(local));
printf("should be zero: %d\n", usesStruct(^void(int x){ }));
return 0;
}
/*
desired global flags: 1879048192
desired stack flags: 1610612736
should be non-zero: 0
should be non-zero: 0
should be non-zero: 1
should be zero: 0
*/

View File

@ -0,0 +1,6 @@
// RUN: %clang_cc1 -triple thumbv7-eabi -target-cpu cortex-a8 -O3 -emit-llvm -o %t %s
void *f0()
{
return __builtin_thread_pointer();
}

View File

@ -360,8 +360,8 @@ void f0() {
tmp_V2LLi = __builtin_ia32_pmuldq128(tmp_V4i, tmp_V4i);
tmp_V4i = __builtin_ia32_pmulld128(tmp_V4i, tmp_V4i);
tmp_V4f = __builtin_ia32_roundps(tmp_V4f, imm_i_0_16);
// tmp_V4f = __builtin_ia32_roundss(tmp_V4f, tmp_V4f, imm_i_0_16);
// tmp_V2d = __builtin_ia32_roundsd(tmp_V2d, tmp_V2d, imm_i_0_16);
tmp_V4f = __builtin_ia32_roundss(tmp_V4f, tmp_V4f, imm_i_0_16);
tmp_V2d = __builtin_ia32_roundsd(tmp_V2d, tmp_V2d, imm_i_0_16);
tmp_V2d = __builtin_ia32_roundpd(tmp_V2d, imm_i_0_16);
tmp_V4f = __builtin_ia32_insertps128(tmp_V4f, tmp_V4f, tmp_i);
#endif

View File

@ -118,6 +118,7 @@ int main() {
// V(clear_cache, (&N, &N+1));
V(trap, ());
R(extract_return_addr, (&N));
P(signbit, (1.0));
return 0;
}

View File

@ -0,0 +1,57 @@
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
// CHECK: @_ZZ4FUNCvEN4SSSSC1ERKf
// CHECK: @_ZZ4FUNCvEN4SSSSC2E_0RKf
// CHECK: @_ZZ4GORFfEN4SSSSC1ERKf
// CHECK: @_ZZ4GORFfEN4SSSSC2E_0RKf
void FUNC ()
{
{
float IVAR1 ;
struct SSSS
{
float bv;
SSSS( const float& from): bv(from) { }
};
SSSS VAR1(IVAR1);
}
{
float IVAR2 ;
struct SSSS
{
SSSS( const float& from) {}
};
SSSS VAR2(IVAR2);
}
}
void GORF (float IVAR1)
{
{
struct SSSS
{
float bv;
SSSS( const float& from): bv(from) { }
};
SSSS VAR1(IVAR1);
}
{
float IVAR2 ;
struct SSSS
{
SSSS( const float& from) {}
};
SSSS VAR2(IVAR2);
}
}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -emit-llvm -o %t %s
// RUN: %clang_cc1 -emit-llvm -o - %s
typedef struct objc_class *Class;
@ -48,3 +48,19 @@ id Test2() {
return (*[Foo method]).isa;
return [Foo method]->isa;
}
// rdar 7709015
@interface Cat {}
@end
@interface SuperCat : Cat {}
+(void)geneticallyAlterCat:(Cat *)cat;
@end
@implementation SuperCat
+ (void)geneticallyAlterCat:(Cat *)cat {
Class dynamicSubclass;
((id)cat)->isa = dynamicSubclass;
}
@end

View File

@ -9,15 +9,18 @@ void bar(int y) {
int k;
}
extern int n;
static int wibble(int);
// CHECK: EnumDecl=Baz:3:6 (Definition)linkage=External
// CHECK: EnumConstantDecl=Qux:3:12 (Definition)linkage=External
// CHECK: VarDecl=x:4:5linkage=External
// CHECK: FunctionDecl=foo:5:6linkage=External
// CHECK: VarDecl=w:6:12linkage=External
// CHECK: VarDecl=w:6:12linkage=Internal
// CHECK: FunctionDecl=bar:7:6 (Definition)linkage=External
// CHECK: ParmDecl=y:7:14 (Definition)linkage=External
// CHECK: VarDecl=z:8:14 (Definition)linkage=External
// CHECK: VarDecl=k:9:7 (Definition)linkage=External
// CHECK: VarDecl=n:11:12
// CHECK: ParmDecl=y:7:14 (Definition)linkage=NoLinkage
// CHECK: VarDecl=z:8:14 (Definition)linkage=NoLinkage
// CHECK: VarDecl=k:9:7 (Definition)linkage=NoLinkage
// CHECK: VarDecl=n:11:12linkage=External
// CHECK: FunctionDecl=wibble:12:12linkage=Internal
// CHECL: ParmDecl=:12:22 (Definition)linkage=NoLinkage

View File

@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o - %s
// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
// radar 7540194
extern "C" __declspec(dllexport) void BreakTheRewriter(int i) {

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
// radar 7583971
@ -29,5 +29,3 @@
_internal->response->InnerResponse = 0;
}
@end
// CHECK-LP: ((struct NSURLResponse_IMPL *)((struct NSCachedURLResponseInternal_IMPL *)((struct NSCachedURLResponse_IMPL *)self)->_internal)->response)->InnerResponse

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"id=void*" -D"__declspec(X)=" %t-rw.cpp
// radar 7589414
@protocol NSPortDelegate;
@ -30,12 +30,3 @@ void f() {
id a;
id b = bar((id <Proto>)a);
}
// CHECK-LP: NSConnection /*<NSPortDelegate>*/ *conn = 0;
// CHECK-LP: id /*<NSPortDelegate>*/ *idc = 0;
// CHECK-LP: func(id/*<Proto1, Proto2>*/ inProxy);
// CHECK-LP: bar((id /*<Proto>*/)a);

View File

@ -0,0 +1,11 @@
// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
// RUN: %clang_cc1 -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -emit-llvm -o %t-rw.ll
// RUN: FileCheck --input-file=%t-rw.ll %s
typedef void (^void_block_t)(void);
static const void_block_t myblock = ^{
};
// CHECK: myblock = internal global

View File

@ -13,6 +13,10 @@ int main(int argc, char **argv) {
int (^XXX)(void) = ^{ return III+JJJJ; };
// rdar 7671883
__block char array[10] = {'a', 'b', 'c', 'd'};
char (^ch)() = ^{ array[1] = 'X'; return array[5]; };
ch();
return 0;
}

View File

@ -140,13 +140,13 @@ L2: ;
L3:
L4:
goto *P; // expected-error {{illegal indirect goto in protected scope, unknown effect on scopes}}
goto *P; // expected-warning {{illegal indirect goto in protected scope, unknown effect on scopes}}
goto L3; // ok
goto L4; // ok
void *Ptrs[] = {
&&L2, // Ok.
&&L3 // expected-error {{address taken of label in protected scope, jump to it would have unknown effect on scope}}
&&L3 // expected-warning {{address taken of label in protected scope, jump to it would have unknown effect on scope}}
};
}

View File

@ -37,3 +37,8 @@ void Gorf() // expected-error {{redefinition of 'Gorf' as different kind of symb
@interface A(Cat)<P> @end // expected-note {{previous definition is here}}
@interface A(Cat)<Q> @end // expected-warning {{duplicate definition of category 'Cat' on interface 'A'}}
// rdar 7626768
@class NSString;
NSString * TestBaz; // expected-note {{previous definition is here}}
NSString * const TestBaz; // expected-error {{redefinition of 'TestBaz' with a different type}}

View File

@ -39,7 +39,15 @@ void test2() {
// instance variables, which GCC does not.
//===------------------------------------------------------------------------===
#if __has_feature(attribute_objc_ivar_unused)
#define UNUSED_IVAR __attribute__((unused))
#else
#error __attribute__((unused)) not supported on ivars
#endif
@interface TestUnusedIvar {
id x __attribute__((unused)); // no-warning
id y __attribute__((unused)); // no-warning
id x UNUSED_IVAR; // no-warning
}
@end

View File

@ -97,6 +97,18 @@ if config.test_exec_root is None:
###
import re
site_exp = {}
for line in open(os.path.join(config.llvm_obj_root, 'test', 'site.exp')):
m = re.match('set ([^ ]+) "([^"]*)"', line)
if m:
site_exp[m.group(1)] = m.group(2)
targets = set(site_exp['TARGETS_TO_BUILD'].split())
def llvm_supports_target(name):
return name in targets
config.conditions['TARGET'] = llvm_supports_target
# Discover the 'clang' and 'clangcc' to use.
import os

View File

@ -104,7 +104,8 @@ class ArgsCrashTracerInfo {
{
{
llvm::raw_svector_ostream Out(CrashString);
Out << "ClangCIndex [createTranslationUnitFromSourceFile]: clang";
Out << "ClangCIndex [" << getClangFullVersion() << "]"
<< "[createTranslationUnitFromSourceFile]: clang";
for (llvm::SmallVectorImpl<const char*>::iterator I=Args.begin(),
E=Args.end(); I!=E; ++I)
Out << ' ' << *I;
@ -1002,7 +1003,8 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
// FIXME: Until we have broader testing, just drop the entire AST if we
// encountered an error.
if (NumErrors != Diags->getNumErrors()) {
if (CXXIdx->getDisplayDiagnostics()) {
// Make sure to check that 'Unit' is non-NULL.
if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
for (ASTUnit::diag_iterator D = Unit->diag_begin(),
DEnd = Unit->diag_end();
D != DEnd; ++D) {
@ -1527,6 +1529,8 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
if (SLoc.isValid()) {
@ -2052,6 +2056,8 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
if (!CXXUnit || !Tokens || !NumTokens)
return;
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
SourceRange R = cxloc::translateCXSourceRange(Range);
if (R.isInvalid())
return;
@ -2175,6 +2181,8 @@ void clang_annotateTokens(CXTranslationUnit TU,
if (!CXXUnit || !Tokens)
return;
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
// Annotate all of the source locations in the region of interest that map
SourceRange RegionOfInterest;
RegionOfInterest.setBegin(

View File

@ -431,10 +431,10 @@ static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
switch (clang_getCursorLinkage(cursor)) {
case CXLinkage_Invalid: break;
case CXLinkage_NoLinkage: linkage = "NoLinkage";
case CXLinkage_Internal: linkage = "Internal";
case CXLinkage_UniqueExternal: linkage = "UniqueExternal";
case CXLinkage_External: linkage = "External";
case CXLinkage_NoLinkage: linkage = "NoLinkage"; break;
case CXLinkage_Internal: linkage = "Internal"; break;
case CXLinkage_UniqueExternal: linkage = "UniqueExternal"; break;
case CXLinkage_External: linkage = "External"; break;
}
if (linkage) {