Update clang to r97873.
This commit is contained in:
parent
79ade4e028
commit
dd5132ce25
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
20
include/clang/Basic/BuiltinsARM.def
Normal file
20
include/clang/Basic/BuiltinsARM.def
Normal 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
|
@ -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", "")
|
||||
|
||||
|
||||
|
@ -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<
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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>;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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!");
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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() {}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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)) {
|
||||
|
@ -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())
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
/// @}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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); }
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
130
lib/Headers/smmintrin.h
Normal 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 */
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
15
test/Analysis/inline3.c
Normal 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();
|
||||
}
|
63
test/CXX/class.derived/class.member.lookup/p8.cpp
Normal file
63
test/CXX/class.derived/class.member.lookup/p8.cpp
Normal 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>);
|
40
test/CXX/except/except.handle/p16.cpp
Normal file
40
test/CXX/except/except.handle/p16.cpp
Normal 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}}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
||||
}
|
||||
|
62
test/CodeGen/attr-weakref.c
Normal file
62
test/CodeGen/attr-weakref.c
Normal 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;
|
||||
}
|
54
test/CodeGen/attr-weakref2.c
Normal file
54
test/CodeGen/attr-weakref2.c
Normal 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;
|
||||
}
|
@ -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
106
test/CodeGen/blockstret.c
Normal 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
|
||||
|
||||
*/
|
6
test/CodeGen/builtins-arm.c
Normal file
6
test/CodeGen/builtins-arm.c
Normal 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();
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
57
test/CodeGenCXX/mangle-local-class-names.cpp
Normal file
57
test/CodeGenCXX/mangle-local-class-names.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
11
test/Rewriter/rewrite-static-block.mm
Normal file
11
test/Rewriter/rewrite-static-block.mm
Normal 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
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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}}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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}}
|
||||
|
@ -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
|
||||
|
||||
|
12
test/lit.cfg
12
test/lit.cfg
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user