diff options
Diffstat (limited to 'lib/Basic')
-rw-r--r-- | lib/Basic/CMakeLists.txt | 26 | ||||
-rw-r--r-- | lib/Basic/Diagnostic.cpp | 17 | ||||
-rw-r--r-- | lib/Basic/IdentifierTable.cpp | 2 | ||||
-rw-r--r-- | lib/Basic/Module.cpp | 51 | ||||
-rw-r--r-- | lib/Basic/OpenMPKinds.cpp | 43 | ||||
-rw-r--r-- | lib/Basic/SourceManager.cpp | 41 | ||||
-rw-r--r-- | lib/Basic/TargetInfo.cpp | 5 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 362 | ||||
-rw-r--r-- | lib/Basic/Version.cpp | 4 |
9 files changed, 487 insertions, 64 deletions
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt index 37efcb1220..34111691c8 100644 --- a/lib/Basic/CMakeLists.txt +++ b/lib/Basic/CMakeLists.txt @@ -11,6 +11,7 @@ add_clang_library(clangBasic LangOptions.cpp Module.cpp ObjCRuntime.cpp + OpenMPKinds.cpp OperatorPrecedence.cpp SourceLocation.cpp SourceManager.cpp @@ -28,9 +29,25 @@ if( NOT IS_SYMLINK "${CLANG_SOURCE_DIR}" ) # See PR 8437 find_package(Subversion) endif() if (Subversion_FOUND AND EXISTS "${CLANG_SOURCE_DIR}/.svn") - Subversion_WC_INFO(${CLANG_SOURCE_DIR} CLANG) + # Create custom target to generate the Subversion version include. + add_custom_target(clang_revision_tag ALL + COMMAND ${CMAKE_COMMAND} -DFIRST_SOURCE_DIR=${LLVM_MAIN_SRC_DIR} + -DFIRST_REPOSITORY=LLVM_REPOSITORY + -DSECOND_SOURCE_DIR=${CLANG_SOURCE_DIR} + -DSECOND_REPOSITORY=SVN_REPOSITORY + -DHEADER_FILE=${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc + -P ${LLVM_MAIN_SRC_DIR}/cmake/modules/GetSVN.cmake) + + # Mark the generated header as being generated. +message(STATUS "Expecting header to go in ${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc") + set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc + PROPERTIES GENERATED TRUE + HEADER_FILE_ONLY TRUE) + + # Tell Version.cpp that it needs to build with -DHAVE_SVN_VERSION_INC. set_source_files_properties(Version.cpp - PROPERTIES COMPILE_DEFINITIONS "SVN_REVISION=\"${CLANG_WC_REVISION}\"") + PROPERTIES COMPILE_DEFINITIONS "HAVE_SVN_VERSION_INC") + endif() add_dependencies(clangBasic @@ -49,3 +66,8 @@ add_dependencies(clangBasic ClangDiagnosticSema ClangDiagnosticSerialization ) + +# clangBasic depends on the version. +if (Subversion_FOUND AND EXISTS "${CLANG_SOURCE_DIR}/.svn") + add_dependencies(clangBasic clang_revision_tag) +endif()
\ No newline at end of file diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 842bacb9a5..45d4b539e8 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -971,6 +971,23 @@ bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; } void IgnoringDiagConsumer::anchor() { } +ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() {} + +void ForwardingDiagnosticConsumer::HandleDiagnostic( + DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) { + Target.HandleDiagnostic(DiagLevel, Info); +} + +void ForwardingDiagnosticConsumer::clear() { + DiagnosticConsumer::clear(); + Target.clear(); +} + +bool ForwardingDiagnosticConsumer::IncludeInDiagnosticCounts() const { + return Target.IncludeInDiagnosticCounts(); +} + PartialDiagnostic::StorageAllocator::StorageAllocator() { for (unsigned I = 0; I != NumCached; ++I) FreeList[I] = Cached + I; diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index 429d9d8cb2..951c718d18 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -65,7 +65,7 @@ namespace { }; } -IdentifierIterator *IdentifierInfoLookup::getIdentifiers() const { +IdentifierIterator *IdentifierInfoLookup::getIdentifiers() { return new EmptyLookupIterator(); } diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp index 65deac1b4a..13518cde66 100644 --- a/lib/Basic/Module.cpp +++ b/lib/Basic/Module.cpp @@ -15,6 +15,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" @@ -27,7 +28,8 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), InferSubmodules(false), InferExplicitSubmodules(false), - InferExportWildcard(false), NameVisibility(Hidden) + InferExportWildcard(false), ConfigMacrosExhaustive(false), + NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) @@ -45,7 +47,6 @@ Module::~Module() { I != IEnd; ++I) { delete *I; } - } /// \brief Determine whether a translation unit built using the current @@ -129,6 +130,19 @@ const DirectoryEntry *Module::getUmbrellaDir() const { return Umbrella.dyn_cast<const DirectoryEntry *>(); } +ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { + if (!TopHeaderNames.empty()) { + for (std::vector<std::string>::iterator + I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { + if (const FileEntry *FE = FileMgr.getFile(*I)) + TopHeaders.insert(FE); + } + TopHeaderNames.clear(); + } + + return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); +} + void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target) { Requires.push_back(Feature); @@ -265,7 +279,20 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS.write_escaped(UmbrellaDir->getName()); OS << "\"\n"; } - + + if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { + OS.indent(Indent + 2); + OS << "config_macros "; + if (ConfigMacrosExhaustive) + OS << "[exhaustive]"; + for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { + if (I) + OS << ", "; + OS << ConfigMacros[I]; + } + OS << "\n"; + } + for (unsigned I = 0, N = Headers.size(); I != N; ++I) { OS.indent(Indent + 2); OS << "header \""; @@ -320,6 +347,24 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS << "\""; } + for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "conflict "; + printModuleId(OS, UnresolvedConflicts[I].Id); + OS << ", \""; + OS.write_escaped(UnresolvedConflicts[I].Message); + OS << "\"\n"; + } + + for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "conflict "; + OS << Conflicts[I].Other->getFullModuleName(); + OS << ", \""; + OS.write_escaped(Conflicts[I].Message); + OS << "\"\n"; + } + if (InferSubmodules) { OS.indent(Indent + 2); if (InferExplicitSubmodules) diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp new file mode 100644 index 0000000000..835908d2a1 --- /dev/null +++ b/lib/Basic/OpenMPKinds.cpp @@ -0,0 +1,43 @@ +//===--- OpenMPKinds.cpp - Token Kinds Support ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// \brief This file implements the OpenMP enum and support functions. +/// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/IdentifierTable.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include <cassert> + +using namespace clang; + +OpenMPDirectiveKind clang::getOpenMPDirectiveKind(StringRef Str) { + return llvm::StringSwitch<OpenMPDirectiveKind>(Str) +#define OPENMP_DIRECTIVE(Name) \ + .Case(#Name, OMPD_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPD_unknown); +} + +const char *clang::getOpenMPDirectiveName(OpenMPDirectiveKind Kind) { + assert(Kind < NUM_OPENMP_DIRECTIVES); + switch (Kind) { + case OMPD_unknown: + return ("unknown"); +#define OPENMP_DIRECTIVE(Name) \ + case OMPD_##Name : return #Name; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + llvm_unreachable("Invalid OpenMP directive kind"); +} diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 1b8383bc42..d6dc6d6328 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -1848,23 +1848,42 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const { return Loc; } +std::pair<FileID, unsigned> +SourceManager::getDecomposedIncludedLoc(FileID FID) const { + // Uses IncludedLocMap to retrieve/cache the decomposed loc. + + typedef std::pair<FileID, unsigned> DecompTy; + typedef llvm::DenseMap<FileID, DecompTy> MapTy; + std::pair<MapTy::iterator, bool> + InsertOp = IncludedLocMap.insert(std::make_pair(FID, DecompTy())); + DecompTy &DecompLoc = InsertOp.first->second; + if (!InsertOp.second) + return DecompLoc; // already in map. + + SourceLocation UpperLoc; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID); + if (Entry.isExpansion()) + UpperLoc = Entry.getExpansion().getExpansionLocStart(); + else + UpperLoc = Entry.getFile().getIncludeLoc(); + + if (UpperLoc.isValid()) + DecompLoc = getDecomposedLoc(UpperLoc); + + return DecompLoc; +} + /// Given a decomposed source location, move it up the include/expansion stack /// to the parent source location. If this is possible, return the decomposed /// version of the parent in Loc and return false. If Loc is the top-level /// entry, return true and don't modify it. static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc, const SourceManager &SM) { - SourceLocation UpperLoc; - const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(Loc.first); - if (Entry.isExpansion()) - UpperLoc = Entry.getExpansion().getExpansionLocStart(); - else - UpperLoc = Entry.getFile().getIncludeLoc(); - - if (UpperLoc.isInvalid()) + std::pair<FileID, unsigned> UpperLoc = SM.getDecomposedIncludedLoc(Loc.first); + if (UpperLoc.first.isInvalid()) return true; // We reached the top. - - Loc = SM.getDecomposedLoc(UpperLoc); + + Loc = UpperLoc; return false; } @@ -1929,7 +1948,7 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // of the other looking for a match. // We use a map from FileID to Offset to store the chain. Easier than writing // a custom set hash info that only depends on the first part of a pair. - typedef llvm::DenseMap<FileID, unsigned> LocSet; + typedef llvm::SmallDenseMap<FileID, unsigned, 16> LocSet; LocSet LChain; do { LChain.insert(LOffs); diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 70ea2351ec..0d44dc010e 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -37,6 +37,7 @@ TargetInfo::TargetInfo(const std::string &T) : TargetOpts(), Triple(T) LongWidth = LongAlign = 32; LongLongWidth = LongLongAlign = 64; SuitableAlign = 64; + MinGlobalAlign = 0; HalfWidth = 16; HalfAlign = 16; FloatWidth = 32; @@ -373,7 +374,9 @@ bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const { Name++; } - return true; + // If a constraint allows neither memory nor register operands it contains + // only modifiers. Reject it. + return Info.allowsMemory() || Info.allowsRegister(); } bool TargetInfo::resolveSymbolicName(const char *&Name, diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index b7cd3dce7c..a622a11aa5 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -621,7 +621,7 @@ class NaClTargetInfo : public OSTargetInfo<Target> { this->SizeType = TargetInfo::UnsignedInt; this->PtrDiffType = TargetInfo::SignedInt; this->IntPtrType = TargetInfo::SignedInt; - this->RegParmMax = 2; + // RegParmMax is inherited from the underlying architecture this->LongDoubleFormat = &llvm::APFloat::IEEEdouble; this->DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" "f32:32:32-f64:64:64-p:32:32:32-v128:32:32"; @@ -1029,7 +1029,8 @@ void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { bool PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, bool Enabled) const { - if (Name == "altivec" || Name == "qpx") { + if (Name == "altivec" || Name == "fprnd" || Name == "mfocrf" || + Name == "popcntd" || Name == "qpx") { Features[Name] = Enabled; return true; } @@ -1301,7 +1302,14 @@ namespace { return TargetInfo::CharPtrBuiltinVaList; } virtual bool setCPU(const std::string &Name) { - return Name == "sm_10" || Name == "sm_13" || Name == "sm_20"; + bool Valid = llvm::StringSwitch<bool>(Name) + .Case("sm_20", true) + .Case("sm_21", true) + .Case("sm_30", true) + .Case("sm_35", true) + .Default(false); + + return Valid; } virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, @@ -1484,7 +1492,7 @@ public: .Case("caicos", GK_NORTHERN_ISLANDS) .Case("cayman", GK_CAYMAN) .Case("aruba", GK_CAYMAN) - .Case("SI", GK_SOUTHERN_ISLANDS) + .Case("tahiti", GK_SOUTHERN_ISLANDS) .Case("pitcairn", GK_SOUTHERN_ISLANDS) .Case("verde", GK_SOUTHERN_ISLANDS) .Case("oland", GK_SOUTHERN_ISLANDS) @@ -1701,6 +1709,8 @@ class X86TargetInfo : public TargetInfo { bool HasBMI2; bool HasPOPCNT; bool HasRTM; + bool HasPRFCHW; + bool HasRDSEED; bool HasSSE4a; bool HasFMA4; bool HasFMA; @@ -1825,6 +1835,7 @@ class X86TargetInfo : public TargetInfo { /// Bobcat architecture processors. //@{ CK_BTVER1, + CK_BTVER2, //@} /// \name Bulldozer @@ -1852,8 +1863,8 @@ public: : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow), HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasRDRND(false), HasBMI(false), HasBMI2(false), HasPOPCNT(false), HasRTM(false), - HasSSE4a(false), HasFMA4(false), HasFMA(false), HasXOP(false), - HasF16C(false), CPU(CK_Generic) { + HasPRFCHW(false), HasRDSEED(false), HasSSE4a(false), HasFMA4(false), + HasFMA(false), HasXOP(false), HasF16C(false), CPU(CK_Generic) { BigEndian = false; LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } @@ -1949,6 +1960,7 @@ public: .Case("opteron-sse3", CK_OpteronSSE3) .Case("amdfam10", CK_AMDFAM10) .Case("btver1", CK_BTVER1) + .Case("btver2", CK_BTVER2) .Case("bdver1", CK_BDVER1) .Case("bdver2", CK_BDVER2) .Case("x86-64", CK_x86_64) @@ -2014,6 +2026,7 @@ public: case CK_OpteronSSE3: case CK_AMDFAM10: case CK_BTVER1: + case CK_BTVER2: case CK_BDVER1: case CK_BDVER2: case CK_x86_64: @@ -2059,6 +2072,8 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { Features["bmi2"] = false; Features["popcnt"] = false; Features["rtm"] = false; + Features["prfchw"] = false; + Features["rdseed"] = false; Features["fma4"] = false; Features["fma"] = false; Features["xop"] = false; @@ -2181,6 +2196,15 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { setFeatureEnabled(Features, "lzcnt", true); setFeatureEnabled(Features, "popcnt", true); break; + case CK_BTVER2: + setFeatureEnabled(Features, "avx", true); + setFeatureEnabled(Features, "sse4a", true); + setFeatureEnabled(Features, "lzcnt", true); + setFeatureEnabled(Features, "aes", true); + setFeatureEnabled(Features, "pclmul", true); + setFeatureEnabled(Features, "bmi", true); + setFeatureEnabled(Features, "f16c", true); + break; case CK_BDVER1: setFeatureEnabled(Features, "xop", true); setFeatureEnabled(Features, "lzcnt", true); @@ -2281,6 +2305,10 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, Features["f16c"] = true; else if (Name == "rtm") Features["rtm"] = true; + else if (Name == "prfchw") + Features["prfchw"] = true; + else if (Name == "rdseed") + Features["rdseed"] = true; } else { if (Name == "mmx") Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false; @@ -2345,6 +2373,10 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, Features["f16c"] = false; else if (Name == "rtm") Features["rtm"] = false; + else if (Name == "prfchw") + Features["prfchw"] = false; + else if (Name == "rdseed") + Features["rdseed"] = false; } return true; @@ -2401,6 +2433,16 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { continue; } + if (Feature == "prfchw") { + HasPRFCHW = true; + continue; + } + + if (Feature == "rdseed") { + HasRDSEED = true; + continue; + } + if (Feature == "sse4a") { HasSSE4a = true; continue; @@ -2581,6 +2623,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_BTVER1: defineCPUMacros(Builder, "btver1"); break; + case CK_BTVER2: + defineCPUMacros(Builder, "btver2"); + break; case CK_BDVER1: defineCPUMacros(Builder, "bdver1"); break; @@ -2625,6 +2670,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasRTM) Builder.defineMacro("__RTM__"); + if (HasPRFCHW) + Builder.defineMacro("__PRFCHW__"); + + if (HasRDSEED) + Builder.defineMacro("__RDSEED__"); + if (HasSSE4a) Builder.defineMacro("__SSE4A__"); @@ -2694,6 +2745,14 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case NoMMX3DNow: break; } + + if (CPU >= CK_i486) { + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); + } + if (CPU >= CK_i586) + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } bool X86TargetInfo::hasFeature(StringRef Feature) const { @@ -2713,6 +2772,8 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("pclmul", HasPCLMUL) .Case("popcnt", HasPOPCNT) .Case("rtm", HasRTM) + .Case("prfchw", HasPRFCHW) + .Case("rdseed", HasRDSEED) .Case("sse", SSELevel >= SSE1) .Case("sse2", SSELevel >= SSE2) .Case("sse3", SSELevel >= SSE3) @@ -3246,6 +3307,8 @@ namespace { class AArch64TargetInfo : public TargetInfo { static const char * const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; + + static const Builtin::Info BuiltinInfo[]; public: AArch64TargetInfo(const std::string& triple) : TargetInfo(triple) { BigEndian = false; @@ -3277,45 +3340,45 @@ public: // FIXME: these were written based on an unreleased version of a 32-bit ACLE // which was intended to be compatible with a 64-bit implementation. They // will need updating when a real 64-bit ACLE exists. Particularly pressing - // instances are: __AARCH_ISA_A32, __AARCH_ISA_T32, __ARCH_PCS. - Builder.defineMacro("__AARCH_ACLE", "101"); - Builder.defineMacro("__AARCH", "8"); - Builder.defineMacro("__AARCH_PROFILE", "'A'"); + // instances are: __ARM_ARCH_ISA_ARM, __ARM_ARCH_ISA_THUMB, __ARM_PCS. + Builder.defineMacro("__ARM_ACLE", "101"); + Builder.defineMacro("__ARM_ARCH", "8"); + Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'"); - Builder.defineMacro("__AARCH_FEATURE_UNALIGNED"); - Builder.defineMacro("__AARCH_FEATURE_CLZ"); - Builder.defineMacro("__AARCH_FEATURE_FMA"); + Builder.defineMacro("__ARM_FEATURE_UNALIGNED"); + Builder.defineMacro("__ARM_FEATURE_CLZ"); + Builder.defineMacro("__ARM_FEATURE_FMA"); // FIXME: ACLE 1.1 reserves bit 4. Will almost certainly come to mean // 128-bit LDXP present, at which point this becomes 0x1f. - Builder.defineMacro("__AARCH_FEATURE_LDREX", "0xf"); + Builder.defineMacro("__ARM_FEATURE_LDREX", "0xf"); // 0xe implies support for half, single and double precision operations. - Builder.defineMacro("__AARCH_FP", "0xe"); + Builder.defineMacro("__ARM_FP", "0xe"); // PCS specifies this for SysV variants, which is all we support. Other ABIs - // may choose __AARCH_FP16_FORMAT_ALTERNATIVE. - Builder.defineMacro("__AARCH_FP16_FORMAT_IEEE"); + // may choose __ARM_FP16_FORMAT_ALTERNATIVE. + Builder.defineMacro("__ARM_FP16_FORMAT_IEEE"); if (Opts.FastMath || Opts.FiniteMathOnly) - Builder.defineMacro("__AARCH_FP_FAST"); + Builder.defineMacro("__ARM_FP_FAST"); if ((Opts.C99 || Opts.C11) && !Opts.Freestanding) - Builder.defineMacro("__AARCH_FP_FENV_ROUNDING"); + Builder.defineMacro("__ARM_FP_FENV_ROUNDING"); - Builder.defineMacro("__AARCH_SIZEOF_WCHAR_T", + Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", Opts.ShortWChar ? "2" : "4"); - Builder.defineMacro("__AARCH_SIZEOF_MINIMAL_ENUM", + Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); if (BigEndian) - Builder.defineMacro("__AARCH_BIG_ENDIAN"); + Builder.defineMacro("__ARM_BIG_ENDIAN"); } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { - Records = 0; - NumRecords = 0; + Records = BuiltinInfo; + NumRecords = clang::AArch64::LastTSBuiltin-Builtin::FirstTSBuiltin; } virtual bool hasFeature(StringRef Feature) const { return Feature == "aarch64"; @@ -3424,6 +3487,14 @@ void AArch64TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, NumAliases = llvm::array_lengthof(GCCRegAliases); } + +const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, +#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\ + ALL_LANGUAGES }, +#include "clang/Basic/BuiltinsAArch64.def" +}; + } // end anonymous namespace namespace { @@ -3456,6 +3527,34 @@ class ARMTargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; + static bool shouldUseInlineAtomic(const llvm::Triple &T) { + // On linux, binaries targeting old cpus call functions in libgcc to + // perform atomic operations. The implementation in libgcc then calls into + // the kernel which on armv6 and newer uses ldrex and strex. The net result + // is that if we assume the kernel is at least as recent as the hardware, + // it is safe to use atomic instructions on armv6 and newer. + if (T.getOS() != llvm::Triple::Linux) + return false; + StringRef ArchName = T.getArchName(); + if (T.getArch() == llvm::Triple::arm) { + if (!ArchName.startswith("armv")) + return false; + StringRef VersionStr = ArchName.substr(4); + unsigned Version; + if (VersionStr.getAsInteger(10, Version)) + return false; + return Version >= 6; + } + assert(T.getArch() == llvm::Triple::thumb); + if (!ArchName.startswith("thumbv")) + return false; + StringRef VersionStr = ArchName.substr(6); + unsigned Version; + if (VersionStr.getAsInteger(10, Version)) + return false; + return Version >= 7; + } + public: ARMTargetInfo(const std::string &TripleStr) : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s"), IsAAPCS(true) @@ -3488,8 +3587,9 @@ public: TheCXXABI.set(TargetCXXABI::GenericARM); // ARM has atomics up to 8 bytes - // FIXME: Set MaxAtomicInlineWidth if we have the feature v6e MaxAtomicPromoteWidth = 64; + if (shouldUseInlineAtomic(getTriple())) + MaxAtomicInlineWidth = 64; // Do force alignment of members that follow zero length bitfields. If // the alignment of the zero-length bitfield is greater than the member @@ -4065,16 +4165,14 @@ const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { namespace { -class SparcV8TargetInfo : public TargetInfo { +// Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit). +class SparcTargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; static const char * const GCCRegNames[]; bool SoftFloat; public: - SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { - // FIXME: Support Sparc quad-precision long double? - DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; - } + SparcTargetInfo(const std::string &triple) : TargetInfo(triple) {} + virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, bool Enabled) const { @@ -4094,7 +4192,6 @@ public: virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { DefineStd(Builder, "sparc", Opts); - Builder.defineMacro("__sparcv8"); Builder.defineMacro("__REGISTER_PREFIX__", ""); if (SoftFloat) @@ -4130,20 +4227,20 @@ public: } }; -const char * const SparcV8TargetInfo::GCCRegNames[] = { +const char * const SparcTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" }; -void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names, - unsigned &NumNames) const { +void SparcTargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { Names = GCCRegNames; NumNames = llvm::array_lengthof(GCCRegNames); } -const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { +const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = { { { "g0" }, "r0" }, { { "g1" }, "r1" }, { { "g2" }, "r2" }, @@ -4178,11 +4275,53 @@ const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { { { "i7" }, "r31" }, }; -void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, - unsigned &NumAliases) const { +void SparcTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { Aliases = GCCRegAliases; NumAliases = llvm::array_lengthof(GCCRegAliases); } + +// SPARC v8 is the 32-bit mode selected by Triple::sparc. +class SparcV8TargetInfo : public SparcTargetInfo { +public: + SparcV8TargetInfo(const std::string& triple) : SparcTargetInfo(triple) { + // FIXME: Support Sparc quad-precision long double? + DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64"; + } + + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + SparcTargetInfo::getTargetDefines(Opts, Builder); + Builder.defineMacro("__sparcv8"); + } +}; + +// SPARC v9 is the 64-bit mode selected by Triple::sparcv9. +class SparcV9TargetInfo : public SparcTargetInfo { +public: + SparcV9TargetInfo(const std::string& triple) : SparcTargetInfo(triple) { + // FIXME: Support Sparc quad-precision long double? + DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32:64-S128"; + } + + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + SparcTargetInfo::getTargetDefines(Opts, Builder); + Builder.defineMacro("__sparcv9"); + Builder.defineMacro("__arch64__"); + // Solaris and its derivative AuroraUX don't need these variants, but the + // BSDs do. + if (getTriple().getOS() != llvm::Triple::Solaris && + getTriple().getOS() != llvm::Triple::AuroraUX) { + Builder.defineMacro("__sparc64__"); + Builder.defineMacro("__sparc_v9__"); + Builder.defineMacro("__sparcv9__"); + } + } +}; + } // end anonymous namespace. namespace { @@ -4205,6 +4344,100 @@ public: } // end anonymous namespace. namespace { + class SystemZTargetInfo : public TargetInfo { + static const char *const GCCRegNames[]; + + public: + SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) { + TLSSupported = true; + IntWidth = IntAlign = 32; + LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; + PointerWidth = PointerAlign = 64; + LongDoubleWidth = 128; + LongDoubleAlign = 64; + LongDoubleFormat = &llvm::APFloat::IEEEquad; + MinGlobalAlign = 16; + DescriptionString = "E-p:64:64:64-i1:8:16-i8:8:16-i16:16-i32:32-i64:64" + "-f32:32-f64:64-f128:64-a0:8:16-n32:64"; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("__s390__"); + Builder.defineMacro("__s390x__"); + Builder.defineMacro("__zarch__"); + Builder.defineMacro("__LONG_DOUBLE_128__"); + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + // FIXME: Implement. + Records = 0; + NumRecords = 0; + } + + virtual void getGCCRegNames(const char *const *&Names, + unsigned &NumNames) const; + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + // No aliases. + Aliases = 0; + NumAliases = 0; + } + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &info) const; + virtual const char *getClobbers() const { + // FIXME: Is this really right? + return ""; + } + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::SystemZBuiltinVaList; + } + }; + + const char *const SystemZTargetInfo::GCCRegNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7", + "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15" + }; + + void SystemZTargetInfo::getGCCRegNames(const char *const *&Names, + unsigned &NumNames) const { + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); + } + + bool SystemZTargetInfo:: + validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const { + switch (*Name) { + default: + return false; + + case 'a': // Address register + case 'd': // Data register (equivalent to 'r') + case 'f': // Floating-point register + Info.setAllowsRegister(); + return true; + + case 'I': // Unsigned 8-bit constant + case 'J': // Unsigned 12-bit constant + case 'K': // Signed 16-bit constant + case 'L': // Signed 20-bit displacement (on all targets we support) + case 'M': // 0x7fffffff + return true; + + case 'Q': // Memory with base and unsigned 12-bit displacement + case 'R': // Likewise, plus an index + case 'S': // Memory with base and signed 20-bit displacement + case 'T': // Likewise, plus an index + Info.setAllowsMemory(); + return true; + } + } +} + +namespace { class MSP430TargetInfo : public TargetInfo { static const char * const GCCRegNames[]; public: @@ -4359,8 +4592,10 @@ class MipsTargetInfoBase : public TargetInfo { static const Builtin::Info BuiltinInfo[]; std::string CPU; bool IsMips16; + bool IsMicromips; + bool IsSingleFloat; enum MipsFloatABI { - HardFloat, SingleFloat, SoftFloat + HardFloat, SoftFloat } FloatABI; enum DspRevEnum { NoDSP, DSP1, DSP2 @@ -4376,6 +4611,8 @@ public: : TargetInfo(triple), CPU(CPUStr), IsMips16(false), + IsMicromips(false), + IsSingleFloat(false), FloatABI(HardFloat), DspRev(NoDSP), ABI(ABIStr) @@ -4402,18 +4639,20 @@ public: case HardFloat: Builder.defineMacro("__mips_hard_float", Twine(1)); break; - case SingleFloat: - Builder.defineMacro("__mips_hard_float", Twine(1)); - Builder.defineMacro("__mips_single_float", Twine(1)); - break; case SoftFloat: Builder.defineMacro("__mips_soft_float", Twine(1)); break; } + if (IsSingleFloat) + Builder.defineMacro("__mips_single_float", Twine(1)); + if (IsMips16) Builder.defineMacro("__mips16", Twine(1)); + if (IsMicromips) + Builder.defineMacro("__mips_micromips", Twine(1)); + switch (DspRev) { default: break; @@ -4503,7 +4742,8 @@ public: Name == "o32" || Name == "n32" || Name == "n64" || Name == "eabi" || Name == "mips32" || Name == "mips32r2" || Name == "mips64" || Name == "mips64r2" || - Name == "mips16" || Name == "dsp" || Name == "dspr2") { + Name == "mips16" || Name == "micromips" || + Name == "dsp" || Name == "dspr2") { Features[Name] = Enabled; return true; } else if (Name == "32") { @@ -4518,17 +4758,21 @@ public: virtual void HandleTargetFeatures(std::vector<std::string> &Features) { IsMips16 = false; + IsMicromips = false; + IsSingleFloat = false; FloatABI = HardFloat; DspRev = NoDSP; for (std::vector<std::string>::iterator it = Features.begin(), ie = Features.end(); it != ie; ++it) { if (*it == "+single-float") - FloatABI = SingleFloat; + IsSingleFloat = true; else if (*it == "+soft-float") FloatABI = SoftFloat; else if (*it == "+mips16") IsMips16 = true; + else if (*it == "+micromips") + IsMicromips = true; else if (*it == "+dsp") DspRev = std::max(DspRev, DSP1); else if (*it == "+dspr2") @@ -4816,7 +5060,7 @@ public: this->SizeType = TargetInfo::UnsignedInt; this->PtrDiffType = TargetInfo::SignedInt; this->IntPtrType = TargetInfo::SignedInt; - this->RegParmMax = 2; + this->RegParmMax = 0; // Disallow regparm DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" "f32:32:32-f64:64:64-p:32:32:32-v128:32:32"; } @@ -5142,6 +5386,32 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new SparcV8TargetInfo(T); } + case llvm::Triple::sparcv9: + switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<SparcV9TargetInfo>(T); + case llvm::Triple::AuroraUX: + return new AuroraUXTargetInfo<SparcV9TargetInfo>(T); + case llvm::Triple::Solaris: + return new SolarisTargetInfo<SparcV9TargetInfo>(T); + case llvm::Triple::NetBSD: + return new NetBSDTargetInfo<SparcV9TargetInfo>(T); + case llvm::Triple::OpenBSD: + return new OpenBSDTargetInfo<SparcV9TargetInfo>(T); + case llvm::Triple::FreeBSD: + return new FreeBSDTargetInfo<SparcV9TargetInfo>(T); + default: + return new SparcV9TargetInfo(T); + } + + case llvm::Triple::systemz: + switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<SystemZTargetInfo>(T); + default: + return new SystemZTargetInfo(T); + } + case llvm::Triple::tce: return new TCETargetInfo(T); diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp index cd8c10f215..e219a3def7 100644 --- a/lib/Basic/Version.cpp +++ b/lib/Basic/Version.cpp @@ -18,6 +18,10 @@ #include <cstdlib> #include <cstring> +#ifdef HAVE_SVN_VERSION_INC +# include "SVNVersion.inc" +#endif + namespace clang { std::string getClangRepositoryPath() { |