diff options
author | dim <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
commit | 554bcb69c2d785a011a30e7db87a36a87fe7db10 (patch) | |
tree | 9abb1a658a297776086f4e0dfa6ca533de02104e /lib/Basic | |
parent | bb67ca86b31f67faee50bd10c3b036d65751745a (diff) | |
download | FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.zip FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.tar.gz |
Vendor import of clang trunk r161861:
http://llvm.org/svn/llvm-project/cfe/trunk@161861
Diffstat (limited to 'lib/Basic')
-rw-r--r-- | lib/Basic/CMakeLists.txt | 33 | ||||
-rw-r--r-- | lib/Basic/ConvertUTF.c | 3 | ||||
-rw-r--r-- | lib/Basic/ConvertUTFWrapper.cpp | 70 | ||||
-rw-r--r-- | lib/Basic/Diagnostic.cpp | 129 | ||||
-rw-r--r-- | lib/Basic/DiagnosticIDs.cpp | 32 | ||||
-rw-r--r-- | lib/Basic/FileManager.cpp | 61 | ||||
-rw-r--r-- | lib/Basic/IdentifierTable.cpp | 29 | ||||
-rw-r--r-- | lib/Basic/ObjCRuntime.cpp | 86 | ||||
-rw-r--r-- | lib/Basic/SourceManager.cpp | 96 | ||||
-rw-r--r-- | lib/Basic/TargetInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 588 | ||||
-rw-r--r-- | lib/Basic/Version.cpp | 5 | ||||
-rw-r--r-- | lib/Basic/VersionTuple.cpp | 52 |
13 files changed, 921 insertions, 264 deletions
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt index ef2e93c..73e693b 100644 --- a/lib/Basic/CMakeLists.txt +++ b/lib/Basic/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS mc) add_clang_library(clangBasic Builtins.cpp ConvertUTF.c + ConvertUTFWrapper.cpp Diagnostic.cpp DiagnosticIDs.cpp FileManager.cpp @@ -10,6 +11,7 @@ add_clang_library(clangBasic IdentifierTable.cpp LangOptions.cpp Module.cpp + ObjCRuntime.cpp SourceLocation.cpp SourceManager.cpp TargetInfo.cpp @@ -31,18 +33,19 @@ if (Subversion_FOUND AND EXISTS "${CLANG_SOURCE_DIR}/.svn") PROPERTIES COMPILE_DEFINITIONS "SVN_REVISION=\"${CLANG_WC_REVISION}\"") endif() -add_dependencies(clangBasic - ClangARMNeon - ClangAttrList - ClangDiagnosticAnalysis - ClangDiagnosticAST - ClangDiagnosticCommon - ClangDiagnosticDriver - ClangDiagnosticFrontend - ClangDiagnosticGroups - ClangDiagnosticLex - ClangDiagnosticParse - ClangDiagnosticSema - ClangDiagnosticSerialization - ClangDiagnosticIndexName) - +add_dependencies(clangBasic + ClangARMNeon + ClangAttrList + ClangDiagnosticAnalysis + ClangDiagnosticAST + ClangDiagnosticComment + ClangDiagnosticCommon + ClangDiagnosticDriver + ClangDiagnosticFrontend + ClangDiagnosticGroups + ClangDiagnosticIndexName + ClangDiagnosticLex + ClangDiagnosticParse + ClangDiagnosticSema + ClangDiagnosticSerialization + ) diff --git a/lib/Basic/ConvertUTF.c b/lib/Basic/ConvertUTF.c index e197003..4793b25 100644 --- a/lib/Basic/ConvertUTF.c +++ b/lib/Basic/ConvertUTF.c @@ -285,6 +285,7 @@ ConversionResult ConvertUTF16toUTF8 ( *targetStart = target; return result; } +#endif /* --------------------------------------------------------------------- */ @@ -339,8 +340,6 @@ ConversionResult ConvertUTF32toUTF8 ( return result; } -#endif - /* --------------------------------------------------------------------- */ /* diff --git a/lib/Basic/ConvertUTFWrapper.cpp b/lib/Basic/ConvertUTFWrapper.cpp new file mode 100644 index 0000000..a1b3f7f --- /dev/null +++ b/lib/Basic/ConvertUTFWrapper.cpp @@ -0,0 +1,70 @@ +//===-- ConvertUTFWrapper.cpp - Wrap ConvertUTF.h with clang data types -----=== +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/ConvertUTF.h" +#include "clang/Basic/LLVM.h" + +namespace clang { + +bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source, + char *&ResultPtr) { + assert(WideCharWidth == 1 || WideCharWidth == 2 || WideCharWidth == 4); + ConversionResult result = conversionOK; + // Copy the character span over. + if (WideCharWidth == 1) { + if (!isLegalUTF8String(reinterpret_cast<const UTF8*>(Source.begin()), + reinterpret_cast<const UTF8*>(Source.end()))) + result = sourceIllegal; + memcpy(ResultPtr, Source.data(), Source.size()); + ResultPtr += Source.size(); + } else if (WideCharWidth == 2) { + const UTF8 *sourceStart = (const UTF8*)Source.data(); + // FIXME: Make the type of the result buffer correct instead of + // using reinterpret_cast. + UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr); + ConversionFlags flags = strictConversion; + result = ConvertUTF8toUTF16( + &sourceStart, sourceStart + Source.size(), + &targetStart, targetStart + 2*Source.size(), flags); + if (result == conversionOK) + ResultPtr = reinterpret_cast<char*>(targetStart); + } else if (WideCharWidth == 4) { + const UTF8 *sourceStart = (const UTF8*)Source.data(); + // FIXME: Make the type of the result buffer correct instead of + // using reinterpret_cast. + UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr); + ConversionFlags flags = strictConversion; + result = ConvertUTF8toUTF32( + &sourceStart, sourceStart + Source.size(), + &targetStart, targetStart + 4*Source.size(), flags); + if (result == conversionOK) + ResultPtr = reinterpret_cast<char*>(targetStart); + } + assert((result != targetExhausted) + && "ConvertUTF8toUTFXX exhausted target buffer"); + return result == conversionOK; +} + +bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) { + const UTF32 *SourceStart = &Source; + const UTF32 *SourceEnd = SourceStart + 1; + UTF8 *TargetStart = reinterpret_cast<UTF8 *>(ResultPtr); + UTF8 *TargetEnd = TargetStart + 4; + ConversionResult CR = ConvertUTF32toUTF8(&SourceStart, SourceEnd, + &TargetStart, TargetEnd, + strictConversion); + if (CR != conversionOK) + return false; + + ResultPtr = reinterpret_cast<char*>(TargetStart); + return true; +} + +} // end namespace clang + diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index f7d5d87..e689502 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/CrashRecoveryContext.h" +#include <cctype> using namespace clang; @@ -48,6 +49,9 @@ DiagnosticsEngine::DiagnosticsEngine( ErrorsAsFatal = false; SuppressSystemWarnings = false; SuppressAllDiagnostics = false; + ElideType = true; + PrintTemplateTree = false; + ShowColors = false; ShowOverloads = Ovl_All; ExtBehavior = Ext_Ignore; @@ -115,7 +119,7 @@ void DiagnosticsEngine::Reset() { // Create a DiagState and DiagStatePoint representing diagnostic changes // through command-line. DiagStates.push_back(DiagState()); - PushDiagStatePoint(&DiagStates.back(), SourceLocation()); + DiagStatePoints.push_back(DiagStatePoint(&DiagStates.back(), FullSourceLoc())); } void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1, @@ -155,12 +159,6 @@ DiagnosticsEngine::GetDiagStatePointForLoc(SourceLocation L) const { return Pos; } -/// \brief This allows the client to specify that certain -/// warnings are ignored. Notes can never be mapped, errors can only be -/// mapped to fatal, and WARNINGs and EXTENSIONs can be mapped arbitrarily. -/// -/// \param The source location that this change of diagnostic state should -/// take affect. It can be null if we are setting the latest state. void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map, SourceLocation L) { assert(Diag < diag::DIAG_UPPER_LIMIT && @@ -385,17 +383,34 @@ void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { CurDiagID = ~0U; } -bool DiagnosticsEngine::EmitCurrentDiagnostic() { - // Process the diagnostic, sending the accumulated information to the - // DiagnosticConsumer. - bool Emitted = ProcessDiag(); +bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) { + assert(getClient() && "DiagnosticClient not set!"); + + bool Emitted; + if (Force) { + Diagnostic Info(this); + + // Figure out the diagnostic level of this message. + DiagnosticIDs::Level DiagLevel + = Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this); + + Emitted = (DiagLevel != DiagnosticIDs::Ignored); + if (Emitted) { + // Emit the diagnostic regardless of suppression level. + Diags->EmitDiag(*this, DiagLevel); + } + } else { + // Process the diagnostic, sending the accumulated information to the + // DiagnosticConsumer. + Emitted = ProcessDiag(); + } // Clear out the current diagnostic object. unsigned DiagID = CurDiagID; Clear(); // If there was a delayed diagnostic, emit it now. - if (DelayedDiagID && DelayedDiagID != DiagID) + if (!Force && DelayedDiagID && DelayedDiagID != DiagID) ReportDelayed(); return Emitted; @@ -666,6 +681,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, /// QualTypeVals - Pass a vector of arrays so that QualType names can be /// compared to see if more information is needed to be printed. SmallVector<intptr_t, 2> QualTypeVals; + SmallVector<char, 64> Tree; + for (unsigned i = 0, e = getNumArgs(); i < e; ++i) if (getArgKind(i) == DiagnosticsEngine::ak_qualtype) QualTypeVals.push_back(getRawArg(i)); @@ -717,7 +734,20 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, assert(isdigit(*DiagStr) && "Invalid format for argument in diagnostic"); unsigned ArgNo = *DiagStr++ - '0'; + // Only used for type diffing. + unsigned ArgNo2 = ArgNo; + DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo); + if (Kind == DiagnosticsEngine::ak_qualtype && + ModifierIs(Modifier, ModifierLen, "diff")) { + Kind = DiagnosticsEngine::ak_qualtype_pair; + assert(*DiagStr == ',' && isdigit(*(DiagStr + 1)) && + "Invalid format for diff modifier"); + ++DiagStr; // Comma. + ArgNo2 = *DiagStr++ - '0'; + assert(getArgKind(ArgNo2) == DiagnosticsEngine::ak_qualtype && + "Second value of type diff must be a qualtype"); + } switch (Kind) { // ---- STRINGS ---- @@ -802,18 +832,91 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, FormattedArgs.data(), FormattedArgs.size(), OutStr, QualTypeVals); break; + case DiagnosticsEngine::ak_qualtype_pair: + // Create a struct with all the info needed for printing. + TemplateDiffTypes TDT; + TDT.FromType = getRawArg(ArgNo); + TDT.ToType = getRawArg(ArgNo2); + TDT.ElideType = getDiags()->ElideType; + TDT.ShowColors = getDiags()->ShowColors; + TDT.TemplateDiffUsed = false; + intptr_t val = reinterpret_cast<intptr_t>(&TDT); + + const char *ArgumentEnd = Argument + ArgumentLen; + const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|'); + + // Print the tree. If this diagnostic already has a tree, skip the + // second tree. + if (getDiags()->PrintTemplateTree && Tree.empty()) { + TDT.PrintFromType = true; + TDT.PrintTree = true; + getDiags()->ConvertArgToString(Kind, val, + Modifier, ModifierLen, + Argument, ArgumentLen, + FormattedArgs.data(), + FormattedArgs.size(), + Tree, QualTypeVals); + // If there is no tree information, fall back to regular printing. + if (!Tree.empty()) { + FormatDiagnostic(Pipe + 1, ArgumentEnd, OutStr); + break; + } + } + + // Non-tree printing, also the fall-back when tree printing fails. + // The fall-back is triggered when the types compared are not templates. + const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$'); + const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$'); + + // Append before text + FormatDiagnostic(Argument, FirstDollar, OutStr); + + // Append first type + TDT.PrintTree = false; + TDT.PrintFromType = true; + getDiags()->ConvertArgToString(Kind, val, + Modifier, ModifierLen, + Argument, ArgumentLen, + FormattedArgs.data(), FormattedArgs.size(), + OutStr, QualTypeVals); + if (!TDT.TemplateDiffUsed) + FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype, + TDT.FromType)); + + // Append middle text + FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr); + + // Append second type + TDT.PrintFromType = false; + getDiags()->ConvertArgToString(Kind, val, + Modifier, ModifierLen, + Argument, ArgumentLen, + FormattedArgs.data(), FormattedArgs.size(), + OutStr, QualTypeVals); + if (!TDT.TemplateDiffUsed) + FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype, + TDT.ToType)); + + // Append end text + FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); + break; } // Remember this argument info for subsequent formatting operations. Turn // std::strings into a null terminated string to make it be the same case as // all the other ones. - if (Kind != DiagnosticsEngine::ak_std_string) + if (Kind == DiagnosticsEngine::ak_qualtype_pair) + continue; + else if (Kind != DiagnosticsEngine::ak_std_string) FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo))); else FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_c_string, (intptr_t)getArgStdStr(ArgNo).c_str())); } + + // Append the type tree to the end of the diagnostics. + OutStr.append(Tree.begin(), Tree.end()); } StoredDiagnostic::StoredDiagnostic() { } diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp index 8c33a96..ca96fd2 100644 --- a/lib/Basic/DiagnosticIDs.cpp +++ b/lib/Basic/DiagnosticIDs.cpp @@ -79,6 +79,7 @@ static const StaticDiagInfoRec StaticDiagInfo[] = { #include "clang/Basic/DiagnosticLexKinds.inc" #include "clang/Basic/DiagnosticParseKinds.inc" #include "clang/Basic/DiagnosticASTKinds.inc" +#include "clang/Basic/DiagnosticCommentKinds.inc" #include "clang/Basic/DiagnosticSemaKinds.inc" #include "clang/Basic/DiagnosticAnalysisKinds.inc" #undef DIAG @@ -357,7 +358,7 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, return CustomDiagInfo->getLevel(DiagID); unsigned DiagClass = getBuiltinDiagClass(DiagID); - assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!"); + if (DiagClass == CLASS_NOTE) return DiagnosticIDs::Note; return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag); } @@ -583,24 +584,9 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { assert(Diag.getClient() && "DiagnosticClient not set!"); // Figure out the diagnostic level of this message. - DiagnosticIDs::Level DiagLevel; unsigned DiagID = Info.getID(); - - if (DiagID >= diag::DIAG_UPPER_LIMIT) { - // Handle custom diagnostics, which cannot be mapped. - DiagLevel = CustomDiagInfo->getLevel(DiagID); - } else { - // Get the class of the diagnostic. If this is a NOTE, map it onto whatever - // the diagnostic level was for the previous diagnostic so that it is - // filtered the same as the previous diagnostic. - unsigned DiagClass = getBuiltinDiagClass(DiagID); - if (DiagClass == CLASS_NOTE) { - DiagLevel = DiagnosticIDs::Note; - } else { - DiagLevel = getDiagnosticLevel(DiagID, DiagClass, Info.getLocation(), - Diag); - } - } + DiagnosticIDs::Level DiagLevel + = getDiagnosticLevel(DiagID, Info.getLocation(), Diag); if (DiagLevel != DiagnosticIDs::Note) { // Record that a fatal error occurred only when we see a second @@ -658,6 +644,14 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { } // Finally, report it. + EmitDiag(Diag, DiagLevel); + return true; +} + +void DiagnosticIDs::EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const { + Diagnostic Info(&Diag); + assert(DiagLevel != DiagnosticIDs::Ignored && "Cannot emit ignored diagnostics!"); + Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info); if (Diag.Client->IncludeInDiagnosticCounts()) { if (DiagLevel == DiagnosticIDs::Warning) @@ -665,8 +659,6 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { } Diag.CurDiagID = ~0U; - - return true; } bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const { diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp index fd6d334..c6b894c 100644 --- a/lib/Basic/FileManager.cpp +++ b/lib/Basic/FileManager.cpp @@ -111,6 +111,14 @@ public: } size_t size() const { return UniqueFiles.size(); } + + void erase(const FileEntry *Entry) { + std::string FullPath(GetFullPath(Entry->getName())); + + // Lowercase string because Windows filesystem is case insensitive. + FullPath = StringRef(FullPath).lower(); + UniqueFiles.erase(FullPath); + } }; //===----------------------------------------------------------------------===// @@ -152,6 +160,8 @@ public: } size_t size() const { return UniqueFiles.size(); } + + void erase(const FileEntry *Entry) { UniqueFiles.erase(*Entry); } }; #endif @@ -213,6 +223,10 @@ void FileManager::removeStatCache(FileSystemStatCache *statCache) { PrevCache->setNextStatCache(statCache->getNextStatCache()); } +void FileManager::clearStatCaches() { + StatCache.reset(0); +} + /// \brief Retrieve the directory that the given file name resides in. /// Filename can point to either a real file or a virtual file. static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr, @@ -259,16 +273,14 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { addAncestorsAsVirtualDirs(DirName); } -/// getDirectory - Lookup, cache, and verify the specified directory -/// (real or virtual). This returns NULL if the directory doesn't -/// exist. -/// const DirectoryEntry *FileManager::getDirectory(StringRef DirName, bool CacheFailure) { - // stat doesn't like trailing separators. + // stat doesn't like trailing separators except for root directory. // At least, on Win32 MSVCRT, stat() cannot strip trailing '/'. // (though it can strip '\\') - if (DirName.size() > 1 && llvm::sys::path::is_separator(DirName.back())) + if (DirName.size() > 1 && + DirName != llvm::sys::path::root_path(DirName) && + llvm::sys::path::is_separator(DirName.back())) DirName = DirName.substr(0, DirName.size()-1); ++NumDirLookups; @@ -315,9 +327,6 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName, return &UDE; } -/// getFile - Lookup, cache, and verify the specified file (real or -/// virtual). This returns NULL if the file doesn't exist. -/// const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, bool CacheFailure) { ++NumFileLookups; @@ -483,15 +492,21 @@ void FileManager::FixupRelativePath(SmallVectorImpl<char> &path) const { } llvm::MemoryBuffer *FileManager:: -getBufferForFile(const FileEntry *Entry, std::string *ErrorStr) { +getBufferForFile(const FileEntry *Entry, std::string *ErrorStr, + bool isVolatile) { OwningPtr<llvm::MemoryBuffer> Result; llvm::error_code ec; + uint64_t FileSize = Entry->getSize(); + // If there's a high enough chance that the file have changed since we + // got its size, force a stat before opening it. + if (isVolatile) + FileSize = -1; + const char *Filename = Entry->getName(); // If the file is already open, use the open file descriptor. if (Entry->FD != -1) { - ec = llvm::MemoryBuffer::getOpenFile(Entry->FD, Filename, Result, - Entry->getSize()); + ec = llvm::MemoryBuffer::getOpenFile(Entry->FD, Filename, Result, FileSize); if (ErrorStr) *ErrorStr = ec.message(); @@ -503,7 +518,7 @@ getBufferForFile(const FileEntry *Entry, std::string *ErrorStr) { // Otherwise, open the file. if (FileSystemOpts.WorkingDir.empty()) { - ec = llvm::MemoryBuffer::getFile(Filename, Result, Entry->getSize()); + ec = llvm::MemoryBuffer::getFile(Filename, Result, FileSize); if (ec && ErrorStr) *ErrorStr = ec.message(); return Result.take(); @@ -511,7 +526,7 @@ getBufferForFile(const FileEntry *Entry, std::string *ErrorStr) { SmallString<128> FilePath(Entry->getName()); FixupRelativePath(FilePath); - ec = llvm::MemoryBuffer::getFile(FilePath.str(), Result, Entry->getSize()); + ec = llvm::MemoryBuffer::getFile(FilePath.str(), Result, FileSize); if (ec && ErrorStr) *ErrorStr = ec.message(); return Result.take(); @@ -564,6 +579,18 @@ bool FileManager::getNoncachedStatValue(StringRef Path, return ::stat(FilePath.c_str(), &StatBuf) != 0; } +void FileManager::invalidateCache(const FileEntry *Entry) { + assert(Entry && "Cannot invalidate a NULL FileEntry"); + + SeenFileEntries.erase(Entry->getName()); + + // FileEntry invalidation should not block future optimizations in the file + // caches. Possible alternatives are cache truncation (invalidate last N) or + // invalidation of the whole cache. + UniqueRealFiles.erase(Entry); +} + + void FileManager::GetUniqueIDMapping( SmallVectorImpl<const FileEntry *> &UIDToFiles) const { UIDToFiles.clear(); @@ -584,6 +611,12 @@ void FileManager::GetUniqueIDMapping( UIDToFiles[(*VFE)->getUID()] = *VFE; } +void FileManager::modifyFileEntry(FileEntry *File, + off_t Size, time_t ModificationTime) { + File->Size = Size; + File->ModTime = ModificationTime; +} + void FileManager::PrintStats() const { llvm::errs() << "\n*** File Manager Stats:\n"; diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index 43899f0..4869ae1 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/ErrorHandling.h" +#include <cctype> #include <cstdio> using namespace clang; @@ -103,7 +104,8 @@ namespace { KEYOPENCL = 0x200, KEYC11 = 0x400, KEYARC = 0x800, - KEYALL = 0x0fff + KEYNOMS = 0x01000, + KEYALL = (0xffff & ~KEYNOMS) // Because KEYNOMS is used to exclude. }; } @@ -136,6 +138,9 @@ static void AddKeyword(StringRef Keyword, else if (LangOpts.ObjC2 && (Flags & KEYARC)) AddResult = 2; else if (LangOpts.CPlusPlus && (Flags & KEYCXX0X)) AddResult = 3; + // Don't add this keyword under MicrosoftMode. + if (LangOpts.MicrosoftMode && (Flags & KEYNOMS)) + return; // Don't add this keyword if disabled in this language. if (AddResult == 0) return; @@ -154,8 +159,8 @@ static void AddCXXOperatorKeyword(StringRef Keyword, Info.setIsCPlusPlusOperatorKeyword(); } -/// AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or -/// "property". +/// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector" +/// or "property". static void AddObjCKeyword(StringRef Name, tok::ObjCKeywordKind ObjCID, IdentifierTable &Table) { @@ -335,22 +340,22 @@ public: unsigned Selector::getNumArgs() const { unsigned IIF = getIdentifierInfoFlag(); - if (IIF == ZeroArg) + if (IIF <= ZeroArg) return 0; if (IIF == OneArg) return 1; - // We point to a MultiKeywordSelector (pointer doesn't contain any flags). - MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr); + // We point to a MultiKeywordSelector. + MultiKeywordSelector *SI = getMultiKeywordSelector(); return SI->getNumArgs(); } IdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const { - if (getIdentifierInfoFlag()) { + if (getIdentifierInfoFlag() < MultiArg) { assert(argIndex == 0 && "illegal keyword index"); return getAsIdentifierInfo(); } - // We point to a MultiKeywordSelector (pointer doesn't contain any flags). - MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr); + // We point to a MultiKeywordSelector. + MultiKeywordSelector *SI = getMultiKeywordSelector(); return SI->getIdentifierInfoForSlot(argIndex); } @@ -375,7 +380,7 @@ std::string Selector::getAsString() const { if (InfoPtr == 0) return "<null selector>"; - if (InfoPtr & ArgFlags) { + if (getIdentifierInfoFlag() < MultiArg) { IdentifierInfo *II = getAsIdentifierInfo(); // If the number of arguments is 0 then II is guaranteed to not be null. @@ -388,8 +393,8 @@ std::string Selector::getAsString() const { return II->getName().str() + ":"; } - // We have a multiple keyword selector (no embedded flags). - return reinterpret_cast<MultiKeywordSelector *>(InfoPtr)->getName(); + // We have a multiple keyword selector. + return getMultiKeywordSelector()->getName(); } /// Interpreting the given string using the normal CamelCase diff --git a/lib/Basic/ObjCRuntime.cpp b/lib/Basic/ObjCRuntime.cpp new file mode 100644 index 0000000..9bd433a --- /dev/null +++ b/lib/Basic/ObjCRuntime.cpp @@ -0,0 +1,86 @@ +//===- ObjCRuntime.cpp - Objective-C Runtime Handling -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the ObjCRuntime class, which represents the +// target Objective-C runtime. +// +//===----------------------------------------------------------------------===// +#include "clang/Basic/ObjCRuntime.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang; + +std::string ObjCRuntime::getAsString() const { + std::string Result; + { + llvm::raw_string_ostream Out(Result); + Out << *this; + } + return Result; +} + +raw_ostream &clang::operator<<(raw_ostream &out, const ObjCRuntime &value) { + switch (value.getKind()) { + case ObjCRuntime::MacOSX: out << "macosx"; break; + case ObjCRuntime::FragileMacOSX: out << "macosx-fragile"; break; + case ObjCRuntime::iOS: out << "ios"; break; + case ObjCRuntime::GNUstep: out << "gnustep"; break; + case ObjCRuntime::GCC: out << "gcc"; break; + case ObjCRuntime::ObjFW: out << "objfw"; break; + } + if (value.getVersion() > VersionTuple(0)) { + out << '-' << value.getVersion(); + } + return out; +} + +bool ObjCRuntime::tryParse(StringRef input) { + // Look for the last dash. + std::size_t dash = input.rfind('-'); + + // We permit dashes in the runtime name, and we also permit the + // version to be omitted, so if we see a dash not followed by a + // digit then we need to ignore it. + if (dash != StringRef::npos && dash + 1 != input.size() && + (input[dash+1] < '0' || input[dash+1] > '9')) { + dash = StringRef::npos; + } + + // Everything prior to that must be a valid string name. + Kind kind; + StringRef runtimeName = input.substr(0, dash); + Version = VersionTuple(0); + if (runtimeName == "macosx") { + kind = ObjCRuntime::MacOSX; + } else if (runtimeName == "macosx-fragile") { + kind = ObjCRuntime::FragileMacOSX; + } else if (runtimeName == "ios") { + kind = ObjCRuntime::iOS; + } else if (runtimeName == "gnustep") { + // If no version is specified then default to the most recent one that we + // know about. + Version = VersionTuple(1, 6); + kind = ObjCRuntime::GNUstep; + } else if (runtimeName == "gcc") { + kind = ObjCRuntime::GCC; + } else if (runtimeName == "objfw") { + kind = ObjCRuntime::ObjFW; + } else { + return true; + } + TheKind = kind; + + if (dash != StringRef::npos) { + StringRef verString = input.substr(dash + 1); + if (Version.tryParse(verString)) + return true; + } + + return false; +} diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index cef091c..9ec2474 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -71,7 +71,7 @@ unsigned ContentCache::getSize() const { void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree) { - if (B == Buffer.getPointer()) { + if (B && B == Buffer.getPointer()) { assert(0 && "Replacing with the same buffer"); Buffer.setInt(DoNotFree? DoNotFreeFlag : 0); return; @@ -97,7 +97,10 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, } std::string ErrorStr; - Buffer.setPointer(SM.getFileManager().getBufferForFile(ContentsEntry, &ErrorStr)); + bool isVolatile = SM.userFilesAreVolatile() && !IsSystemFile; + Buffer.setPointer(SM.getFileManager().getBufferForFile(ContentsEntry, + &ErrorStr, + isVolatile)); // If we were unable to open the file, then we are in an inconsistent // situation where the content cache referenced a file which no longer @@ -189,9 +192,9 @@ unsigned LineTableInfo::getLineTableFilenameID(StringRef Name) { } /// AddLineNote - Add a line note to the line table that indicates that there -/// is a #line at the specified FID/Offset location which changes the presumed +/// is a \#line at the specified FID/Offset location which changes the presumed /// location to LineNo/FilenameID. -void LineTableInfo::AddLineNote(int FID, unsigned Offset, +void LineTableInfo::AddLineNote(FileID FID, unsigned Offset, unsigned LineNo, int FilenameID) { std::vector<LineEntry> &Entries = LineEntries[FID]; @@ -219,10 +222,10 @@ void LineTableInfo::AddLineNote(int FID, unsigned Offset, /// AddLineNote This is the same as the previous version of AddLineNote, but is /// used for GNU line markers. If EntryExit is 0, then this doesn't change the -/// presumed #include stack. If it is 1, this is a file entry, if it is 2 then +/// presumed \#include stack. If it is 1, this is a file entry, if it is 2 then /// this is a file exit. FileKind specifies whether this is a system header or /// extern C system header. -void LineTableInfo::AddLineNote(int FID, unsigned Offset, +void LineTableInfo::AddLineNote(FileID FID, unsigned Offset, unsigned LineNo, int FilenameID, unsigned EntryExit, SrcMgr::CharacteristicKind FileKind) { @@ -256,7 +259,7 @@ void LineTableInfo::AddLineNote(int FID, unsigned Offset, /// FindNearestLineEntry - Find the line entry nearest to FID that is before /// it. If there is no line entry before Offset in FID, return null. -const LineEntry *LineTableInfo::FindNearestLineEntry(int FID, +const LineEntry *LineTableInfo::FindNearestLineEntry(FileID FID, unsigned Offset) { const std::vector<LineEntry> &Entries = LineEntries[FID]; assert(!Entries.empty() && "No #line entries for this FID after all!"); @@ -275,7 +278,7 @@ const LineEntry *LineTableInfo::FindNearestLineEntry(int FID, /// \brief Add a new line entry that has already been encoded into /// the internal representation of the line table. -void LineTableInfo::AddEntry(int FID, +void LineTableInfo::AddEntry(FileID FID, const std::vector<LineEntry> &Entries) { LineEntries[FID] = Entries; } @@ -308,7 +311,7 @@ void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, if (LineTable == 0) LineTable = new LineTableInfo(); - LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID); + LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID); } /// AddLineNote - Add a GNU line marker to the line table. @@ -353,7 +356,7 @@ void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, else if (IsFileExit) EntryExit = 2; - LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID, + LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID, EntryExit, FileKind); } @@ -367,8 +370,10 @@ LineTableInfo &SourceManager::getLineTable() { // Private 'Create' methods. //===----------------------------------------------------------------------===// -SourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr) +SourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, + bool UserFilesAreVolatile) : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true), + UserFilesAreVolatile(UserFilesAreVolatile), ExternalSLocEntries(0), LineTable(0), NumLinearScans(0), NumBinaryProbes(0), FakeBufferForRecovery(0), FakeContentCacheForRecovery(0) { @@ -426,7 +431,8 @@ void SourceManager::clearIDTables() { /// getOrCreateContentCache - Create or return a cached ContentCache for the /// specified file. const ContentCache * -SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) { +SourceManager::getOrCreateContentCache(const FileEntry *FileEnt, + bool isSystemFile) { assert(FileEnt && "Didn't specify a file entry to use?"); // Do we already have information about this file? @@ -440,16 +446,22 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) { EntryAlign = std::max(8U, EntryAlign); Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign); - // If the file contents are overridden with contents from another file, - // pass that file to ContentCache. - llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator - overI = OverriddenFiles.find(FileEnt); - if (overI == OverriddenFiles.end()) + if (OverriddenFilesInfo) { + // If the file contents are overridden with contents from another file, + // pass that file to ContentCache. + llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator + overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt); + if (overI == OverriddenFilesInfo->OverriddenFiles.end()) + new (Entry) ContentCache(FileEnt); + else + new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt + : overI->second, + overI->second); + } else { new (Entry) ContentCache(FileEnt); - else - new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt - : overI->second, - overI->second); + } + + Entry->IsSystemFile = isSystemFile; return Entry; } @@ -622,6 +634,8 @@ void SourceManager::overrideFileContents(const FileEntry *SourceFile, const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer, DoNotFree); const_cast<SrcMgr::ContentCache *>(IR)->BufferOverridden = true; + + getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile); } void SourceManager::overrideFileContents(const FileEntry *SourceFile, @@ -632,7 +646,20 @@ void SourceManager::overrideFileContents(const FileEntry *SourceFile, assert(FileInfos.count(SourceFile) == 0 && "This function should be called at the initialization stage, before " "any parsing occurs."); - OverriddenFiles[SourceFile] = NewFile; + getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile; +} + +void SourceManager::disableFileContentsOverride(const FileEntry *File) { + if (!isFileOverridden(File)) + return; + + const SrcMgr::ContentCache *IR = getOrCreateContentCache(File); + const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(0); + const_cast<SrcMgr::ContentCache *>(IR)->ContentsEntry = IR->OrigEntry; + + assert(OverriddenFilesInfo); + OverriddenFilesInfo->OverriddenFiles.erase(File); + OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File); } StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { @@ -995,9 +1022,10 @@ unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, if (MyInvalid) return 1; - if (FilePos >= MemBuf->getBufferSize()) { + // It is okay to request a position just past the end of the buffer. + if (FilePos > MemBuf->getBufferSize()) { if (Invalid) - *Invalid = MyInvalid; + *Invalid = true; return 1; } @@ -1295,7 +1323,7 @@ SourceManager::getFileCharacteristic(SourceLocation Loc) const { assert(LineTable && "Can't have linetable entries without a LineTable!"); // See if there is a #line directive before the location. const LineEntry *Entry = - LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second); + LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second); // If this is before the first line marker, use the file characteristic. if (!Entry) @@ -1305,7 +1333,7 @@ SourceManager::getFileCharacteristic(SourceLocation Loc) const { } /// Return the filename or buffer identifier of the buffer the location is in. -/// Note that this name does not respect #line directives. Use getPresumedLoc +/// Note that this name does not respect \#line directives. Use getPresumedLoc /// for normal clients. const char *SourceManager::getBufferName(SourceLocation Loc, bool *Invalid) const { @@ -1316,7 +1344,7 @@ const char *SourceManager::getBufferName(SourceLocation Loc, /// getPresumedLoc - This method returns the "presumed" location of a -/// SourceLocation specifies. A "presumed location" can be modified by #line +/// SourceLocation specifies. A "presumed location" can be modified by \#line /// or GNU line marker directives. This provides a view on the data that a /// user should see in diagnostics, for example. /// @@ -1360,7 +1388,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const { assert(LineTable && "Can't have linetable entries without a LineTable!"); // See if there is a #line directive before this. If so, get it. if (const LineEntry *Entry = - LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second)) { + LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second)) { // If the LineEntry indicates a filename, use it. if (Entry->FilenameID != -1) Filename = LineTable->getFilename(Entry->FilenameID); @@ -1834,8 +1862,6 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, return LOffs.first < ROffs.first; } -/// PrintStats - Print statistics to stderr. -/// void SourceManager::PrintStats() const { llvm::errs() << "\n*** Source Manager Stats:\n"; llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size() @@ -1887,10 +1913,14 @@ SourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const { } size_t SourceManager::getDataStructureSizes() const { - return llvm::capacity_in_bytes(MemBufferInfos) + size_t size = llvm::capacity_in_bytes(MemBufferInfos) + llvm::capacity_in_bytes(LocalSLocEntryTable) + llvm::capacity_in_bytes(LoadedSLocEntryTable) + llvm::capacity_in_bytes(SLocEntryLoaded) - + llvm::capacity_in_bytes(FileInfos) - + llvm::capacity_in_bytes(OverriddenFiles); + + llvm::capacity_in_bytes(FileInfos); + + if (OverriddenFilesInfo) + size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles); + + return size; } diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 8c49486..db5941a 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -47,6 +47,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) { LargeArrayMinWidth = 0; LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; + MaxVectorAlign = 0; SizeType = UnsignedLong; PtrDiffType = SignedLong; IntMaxType = SignedLongLong; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index dd2a89a..883864f 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -316,6 +316,8 @@ protected: DefineStd(Builder, "linux", Opts); Builder.defineMacro("__gnu_linux__"); Builder.defineMacro("__ELF__"); + if (Triple.getEnvironment() == llvm::Triple::ANDROIDEABI) + Builder.defineMacro("__ANDROID__", "1"); if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); if (Opts.CPlusPlus) @@ -371,6 +373,7 @@ public: OpenBSDTargetInfo(const std::string &triple) : OSTargetInfo<Target>(triple) { this->UserLabelPrefix = ""; + this->TLSSupported = false; llvm::Triple Triple(triple); switch (Triple.getArch()) { @@ -391,6 +394,29 @@ public: } }; +// Bitrig Target +template<typename Target> +class BitrigTargetInfo : public OSTargetInfo<Target> { +protected: + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const { + // Bitrig defines; list based off of gcc output + + Builder.defineMacro("__Bitrig__"); + DefineStd(Builder, "unix", Opts); + Builder.defineMacro("__ELF__"); + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + } +public: + BitrigTargetInfo(const std::string &triple) + : OSTargetInfo<Target>(triple) { + this->UserLabelPrefix = ""; + this->TLSSupported = false; + this->MCountName = "__mcount"; + } +}; + // PSP Target template<typename Target> class PSPTargetInfo : public OSTargetInfo<Target> { @@ -573,12 +599,60 @@ class PPCTargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; static const char * const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; + std::string CPU; public: PPCTargetInfo(const std::string& triple) : TargetInfo(triple) { LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; } + /// \brief Flags for architecture specific defines. + typedef enum { + ArchDefineNone = 0, + ArchDefineName = 1 << 0, // <name> is substituted for arch name. + ArchDefinePpcgr = 1 << 1, + ArchDefinePpcsq = 1 << 2, + ArchDefine440 = 1 << 3, + ArchDefine603 = 1 << 4, + ArchDefine604 = 1 << 5, + ArchDefinePwr4 = 1 << 6, + ArchDefinePwr6 = 1 << 7 + } ArchDefineTypes; + + virtual bool setCPU(const std::string &Name) { + bool CPUKnown = llvm::StringSwitch<bool>(Name) + .Case("generic", true) + .Case("440", true) + .Case("450", true) + .Case("601", true) + .Case("602", true) + .Case("603", true) + .Case("603e", true) + .Case("603ev", true) + .Case("604", true) + .Case("604e", true) + .Case("620", true) + .Case("g3", true) + .Case("7400", true) + .Case("g4", true) + .Case("7450", true) + .Case("g4+", true) + .Case("750", true) + .Case("970", true) + .Case("g5", true) + .Case("a2", true) + .Case("pwr6", true) + .Case("pwr7", true) + .Case("ppc", true) + .Case("ppc64", true) + .Default(false); + + if (CPUKnown) + CPU = Name; + + return CPUKnown; + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { Records = BuiltinInfo; @@ -718,8 +792,6 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__POWERPC__"); if (PointerWidth == 64) { Builder.defineMacro("_ARCH_PPC64"); - Builder.defineMacro("_LP64"); - Builder.defineMacro("__LP64__"); Builder.defineMacro("__powerpc64__"); Builder.defineMacro("__ppc64__"); } else { @@ -727,7 +799,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, } // Target properties. - if (getTriple().getOS() != llvm::Triple::NetBSD) + if (getTriple().getOS() != llvm::Triple::NetBSD && + getTriple().getOS() != llvm::Triple::OpenBSD) Builder.defineMacro("_BIG_ENDIAN"); Builder.defineMacro("__BIG_ENDIAN__"); @@ -742,6 +815,47 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__VEC__", "10206"); Builder.defineMacro("__ALTIVEC__"); } + + // CPU identification. + ArchDefineTypes defs = (ArchDefineTypes)llvm::StringSwitch<int>(CPU) + .Case("440", ArchDefineName) + .Case("450", ArchDefineName | ArchDefine440) + .Case("601", ArchDefineName) + .Case("602", ArchDefineName | ArchDefinePpcgr) + .Case("603", ArchDefineName | ArchDefinePpcgr) + .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) + .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) + .Case("604", ArchDefineName | ArchDefinePpcgr) + .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr) + .Case("620", ArchDefineName | ArchDefinePpcgr) + .Case("7400", ArchDefineName | ArchDefinePpcgr) + .Case("7450", ArchDefineName | ArchDefinePpcgr) + .Case("750", ArchDefineName | ArchDefinePpcgr) + .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr + | ArchDefinePpcsq) + .Case("pwr6", ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("pwr7", ArchDefineName | ArchDefinePwr6 | ArchDefinePpcgr + | ArchDefinePpcsq) + .Default(ArchDefineNone); + + if (defs & ArchDefineName) + Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper())); + if (defs & ArchDefinePpcgr) + Builder.defineMacro("_ARCH_PPCGR"); + if (defs & ArchDefinePpcsq) + Builder.defineMacro("_ARCH_PPCSQ"); + if (defs & ArchDefine440) + Builder.defineMacro("_ARCH_440"); + if (defs & ArchDefine603) + Builder.defineMacro("_ARCH_603"); + if (defs & ArchDefine604) + Builder.defineMacro("_ARCH_604"); + if (defs & (ArchDefinePwr4 | ArchDefinePwr6)) + Builder.defineMacro("_ARCH_PWR4"); + if (defs & ArchDefinePwr6) { + Builder.defineMacro("_ARCH_PWR5"); + Builder.defineMacro("_ARCH_PWR6"); + } } bool PPCTargetInfo::hasFeature(StringRef Feature) const { @@ -878,15 +992,9 @@ public: } } - virtual const char *getVAListDeclaration() const { + virtual BuiltinVaListKind getBuiltinVaListKind() const { // This is the ELF definition, and is overridden by the Darwin sub-target - return "typedef struct __va_list_tag {" - " unsigned char gpr;" - " unsigned char fpr;" - " unsigned short reserved;" - " void* overflow_arg_area;" - " void* reg_save_area;" - "} __builtin_va_list[1];"; + return TargetInfo::PowerABIBuiltinVaList; } }; } // end anonymous namespace. @@ -907,8 +1015,8 @@ public: LongDoubleFormat = &llvm::APFloat::IEEEdouble; } } - virtual const char *getVAListDeclaration() const { - return "typedef char* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::CharPtrBuiltinVaList; } }; } // end anonymous namespace. @@ -927,8 +1035,8 @@ public: DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:32:64-f32:32:32-f64:64:64-v128:128:128-n32"; } - virtual const char *getVAListDeclaration() const { - return "typedef char* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::CharPtrBuiltinVaList; } }; @@ -944,54 +1052,40 @@ public: } // end anonymous namespace. namespace { - static const unsigned PTXAddrSpaceMap[] = { - 0, // opencl_global - 4, // opencl_local - 1 // opencl_constant + static const unsigned NVPTXAddrSpaceMap[] = { + 1, // opencl_global + 3, // opencl_local + 4, // opencl_constant + 1, // cuda_device + 4, // cuda_constant + 3, // cuda_shared }; - class PTXTargetInfo : public TargetInfo { + class NVPTXTargetInfo : public TargetInfo { static const char * const GCCRegNames[]; static const Builtin::Info BuiltinInfo[]; std::vector<llvm::StringRef> AvailableFeatures; public: - PTXTargetInfo(const std::string& triple) : TargetInfo(triple) { + NVPTXTargetInfo(const std::string& triple) : TargetInfo(triple) { BigEndian = false; TLSSupported = false; LongWidth = LongAlign = 64; - AddrSpaceMap = &PTXAddrSpaceMap; + AddrSpaceMap = &NVPTXAddrSpaceMap; // Define available target features - // These must be defined in sorted order! - AvailableFeatures.push_back("compute10"); - AvailableFeatures.push_back("compute11"); - AvailableFeatures.push_back("compute12"); - AvailableFeatures.push_back("compute13"); - AvailableFeatures.push_back("compute20"); - AvailableFeatures.push_back("double"); - AvailableFeatures.push_back("no-fma"); - AvailableFeatures.push_back("ptx20"); - AvailableFeatures.push_back("ptx21"); - AvailableFeatures.push_back("ptx22"); - AvailableFeatures.push_back("ptx23"); - AvailableFeatures.push_back("sm10"); - AvailableFeatures.push_back("sm11"); - AvailableFeatures.push_back("sm12"); - AvailableFeatures.push_back("sm13"); - AvailableFeatures.push_back("sm20"); - AvailableFeatures.push_back("sm21"); - AvailableFeatures.push_back("sm22"); - AvailableFeatures.push_back("sm23"); + // These must be defined in sorted order! + NoAsmVariants = true; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__PTX__"); + Builder.defineMacro("__NVPTX__"); } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { Records = BuiltinInfo; - NumRecords = clang::PTX::LastTSBuiltin-Builtin::FirstTSBuiltin; + NumRecords = clang::NVPTX::LastTSBuiltin-Builtin::FirstTSBuiltin; } virtual bool hasFeature(StringRef Feature) const { - return Feature == "ptx"; + return Feature == "ptx" || Feature == "nvptx"; } virtual void getGCCRegNames(const char * const *&Names, @@ -1011,36 +1105,38 @@ namespace { // FIXME: Is this really right? return ""; } - virtual const char *getVAListDeclaration() const { + virtual BuiltinVaListKind getBuiltinVaListKind() const { // FIXME: implement - return "typedef char* __builtin_va_list;"; + return TargetInfo::CharPtrBuiltinVaList; + } + virtual bool setCPU(const std::string &Name) { + return Name == "sm_10" || Name == "sm_13" || Name == "sm_20"; } - virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, bool Enabled) const; }; - const Builtin::Info PTXTargetInfo::BuiltinInfo[] = { + const Builtin::Info NVPTXTargetInfo::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/BuiltinsPTX.def" +#include "clang/Basic/BuiltinsNVPTX.def" }; - const char * const PTXTargetInfo::GCCRegNames[] = { + const char * const NVPTXTargetInfo::GCCRegNames[] = { "r0" }; - void PTXTargetInfo::getGCCRegNames(const char * const *&Names, + void NVPTXTargetInfo::getGCCRegNames(const char * const *&Names, unsigned &NumNames) const { Names = GCCRegNames; NumNames = llvm::array_lengthof(GCCRegNames); } - bool PTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, - StringRef Name, - bool Enabled) const { + bool NVPTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, + bool Enabled) const { if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(), Name)) { Features[Name] = Enabled; @@ -1050,24 +1146,28 @@ namespace { } } - class PTX32TargetInfo : public PTXTargetInfo { + class NVPTX32TargetInfo : public NVPTXTargetInfo { public: - PTX32TargetInfo(const std::string& triple) : PTXTargetInfo(triple) { + NVPTX32TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) { PointerWidth = PointerAlign = 32; - SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt; + SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt; DescriptionString - = "e-p:32:32-i64:64:64-f64:64:64-n1:8:16:32:64"; - } + = "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-v16:16:16-v32:32:32-v64:64:64-v128:128:128-" + "n16:32:64"; + } }; - class PTX64TargetInfo : public PTXTargetInfo { + class NVPTX64TargetInfo : public NVPTXTargetInfo { public: - PTX64TargetInfo(const std::string& triple) : PTXTargetInfo(triple) { + NVPTX64TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) { PointerWidth = PointerAlign = 64; - SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong; + SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong; DescriptionString - = "e-p:64:64-i64:64:64-f64:64:64-n1:8:16:32:64"; - } + = "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-v16:16:16-v32:32:32-v64:64:64-v128:128:128-" + "n16:32:64"; + } }; } @@ -1096,8 +1196,8 @@ public: return Feature == "mblaze"; } - virtual const char *getVAListDeclaration() const { - return "typedef char* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::CharPtrBuiltinVaList; } virtual const char *getTargetPrefix() const { return "mblaze"; @@ -1245,11 +1345,16 @@ class X86TargetInfo : public TargetInfo { } MMX3DNowLevel; bool HasAES; + bool HasPCLMUL; bool HasLZCNT; + bool HasRDRND; bool HasBMI; bool HasBMI2; bool HasPOPCNT; + bool HasSSE4a; bool HasFMA4; + bool HasFMA; + bool HasXOP; /// \brief Enumeration of all of the X86 CPUs supported by Clang. /// @@ -1394,8 +1499,9 @@ class X86TargetInfo : public TargetInfo { public: X86TargetInfo(const std::string& triple) : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow), - HasAES(false), HasLZCNT(false), HasBMI(false), HasBMI2(false), - HasPOPCNT(false), HasFMA4(false), CPU(CK_Generic) { + HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasRDRND(false), + HasBMI(false), HasBMI2(false), HasPOPCNT(false), HasSSE4a(false), + HasFMA4(false), HasFMA(false), HasXOP(false), CPU(CK_Generic) { BigEndian = false; LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } @@ -1577,13 +1683,17 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { Features["sse42"] = false; Features["sse4a"] = false; Features["aes"] = false; + Features["pclmul"] = false; Features["avx"] = false; Features["avx2"] = false; Features["lzcnt"] = false; + Features["rdrand"] = false; Features["bmi"] = false; Features["bmi2"] = false; Features["popcnt"] = false; Features["fma4"] = false; + Features["fma"] = false; + Features["xop"] = false; // FIXME: This *really* should not be here. @@ -1637,23 +1747,30 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { case CK_Corei7: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse4", true); - setFeatureEnabled(Features, "aes", true); break; case CK_Corei7AVX: + setFeatureEnabled(Features, "mmx", true); + setFeatureEnabled(Features, "avx", true); + setFeatureEnabled(Features, "aes", true); + setFeatureEnabled(Features, "pclmul", true); + break; case CK_CoreAVXi: setFeatureEnabled(Features, "mmx", true); - setFeatureEnabled(Features, "sse4", true); + setFeatureEnabled(Features, "avx", true); setFeatureEnabled(Features, "aes", true); - //setFeatureEnabled(Features, "avx", true); + setFeatureEnabled(Features, "pclmul", true); + setFeatureEnabled(Features, "rdrnd", true); break; case CK_CoreAVX2: setFeatureEnabled(Features, "mmx", true); - setFeatureEnabled(Features, "sse4", true); + setFeatureEnabled(Features, "avx2", true); setFeatureEnabled(Features, "aes", true); + setFeatureEnabled(Features, "pclmul", true); setFeatureEnabled(Features, "lzcnt", true); + setFeatureEnabled(Features, "rdrnd", true); setFeatureEnabled(Features, "bmi", true); setFeatureEnabled(Features, "bmi2", true); - //setFeatureEnabled(Features, "avx2", true); + setFeatureEnabled(Features, "fma", true); break; case CK_K6: case CK_WinChipC6: @@ -1697,11 +1814,13 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { case CK_BTVER1: setFeatureEnabled(Features, "ssse3", true); setFeatureEnabled(Features, "sse4a", true); + break; case CK_BDVER1: case CK_BDVER2: - setFeatureEnabled(Features, "sse4", true); - setFeatureEnabled(Features, "sse4a", true); + setFeatureEnabled(Features, "avx", true); + setFeatureEnabled(Features, "xop", true); setFeatureEnabled(Features, "aes", true); + setFeatureEnabled(Features, "pclmul", true); break; case CK_C3_2: setFeatureEnabled(Features, "mmx", true); @@ -1716,7 +1835,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, // 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")) + (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1" && + Name != "rdrnd")) return false; // FIXME: this should probably use a switch with fall through. @@ -1746,7 +1866,9 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, else if (Name == "3dnowa") Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = true; else if (Name == "aes") - Features["aes"] = true; + Features["sse"] = Features["sse2"] = Features["aes"] = true; + else if (Name == "pclmul") + Features["sse"] = Features["sse2"] = Features["pclmul"] = true; else if (Name == "avx") Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = @@ -1755,15 +1877,27 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = Features["popcnt"] = Features["avx"] = Features["avx2"] = true; + else if (Name == "fma") + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["popcnt"] = Features["avx"] = Features["fma"] = true; else if (Name == "fma4") Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = - Features["popcnt"] = Features["avx"] = Features["fma4"] = true; + Features["popcnt"] = Features["avx"] = Features["sse4a"] = + Features["fma4"] = true; + else if (Name == "xop") + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["popcnt"] = Features["avx"] = Features["sse4a"] = + Features["fma4"] = Features["xop"] = true; else if (Name == "sse4a") Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["lzcnt"] = Features["popcnt"] = Features["sse4a"] = true; + Features["sse4a"] = true; else if (Name == "lzcnt") Features["lzcnt"] = true; + else if (Name == "rdrnd") + Features["rdrand"] = true; else if (Name == "bmi") Features["bmi"] = true; else if (Name == "bmi2") @@ -1776,33 +1910,50 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, else if (Name == "sse") Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = - Features["sse4a"] = false; + Features["sse4a"] = Features["avx"] = Features["avx2"] = + Features["fma"] = Features["fma4"] = Features["aes"] = + Features["pclmul"] = Features["xop"] = false; else if (Name == "sse2") Features["sse2"] = Features["sse3"] = Features["ssse3"] = - Features["sse41"] = Features["sse42"] = Features["sse4a"] = false; + Features["sse41"] = Features["sse42"] = Features["sse4a"] = + Features["avx"] = Features["avx2"] = Features["fma"] = + Features["fma4"] = Features["aes"] = Features["pclmul"] = + Features["xop"] = false; else if (Name == "sse3") Features["sse3"] = Features["ssse3"] = Features["sse41"] = - Features["sse42"] = Features["sse4a"] = false; + Features["sse42"] = Features["sse4a"] = Features["avx"] = + Features["avx2"] = Features["fma"] = Features["fma4"] = + Features["xop"] = false; else if (Name == "ssse3") - Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["avx"] = Features["avx2"] = Features["fma"] = false; else if (Name == "sse4" || Name == "sse4.1") - Features["sse41"] = Features["sse42"] = false; + Features["sse41"] = Features["sse42"] = Features["avx"] = + Features["avx2"] = Features["fma"] = false; else if (Name == "sse4.2") - Features["sse42"] = false; + Features["sse42"] = Features["avx"] = Features["avx2"] = + Features["fma"] = false; else if (Name == "3dnow") Features["3dnow"] = Features["3dnowa"] = false; else if (Name == "3dnowa") Features["3dnowa"] = false; else if (Name == "aes") Features["aes"] = false; + else if (Name == "pclmul") + Features["pclmul"] = false; else if (Name == "avx") - Features["avx"] = Features["avx2"] = Features["fma4"] = false; + Features["avx"] = Features["avx2"] = Features["fma"] = + Features["fma4"] = Features["xop"] = false; else if (Name == "avx2") Features["avx2"] = false; + else if (Name == "fma") + Features["fma"] = false; else if (Name == "sse4a") - Features["sse4a"] = false; + Features["sse4a"] = Features["fma4"] = Features["xop"] = false; else if (Name == "lzcnt") Features["lzcnt"] = false; + else if (Name == "rdrnd") + Features["rdrand"] = false; else if (Name == "bmi") Features["bmi"] = false; else if (Name == "bmi2") @@ -1810,7 +1961,9 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, else if (Name == "popcnt") Features["popcnt"] = false; else if (Name == "fma4") - Features["fma4"] = false; + Features["fma4"] = Features["xop"] = false; + else if (Name == "xop") + Features["xop"] = false; } return true; @@ -1832,11 +1985,21 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { continue; } + if (Feature == "pclmul") { + HasPCLMUL = true; + continue; + } + if (Feature == "lzcnt") { HasLZCNT = true; continue; } + if (Feature == "rdrand") { + HasRDRND = true; + continue; + } + if (Feature == "bmi") { HasBMI = true; continue; @@ -1852,11 +2015,26 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { continue; } + if (Feature == "sse4a") { + HasSSE4a = true; + continue; + } + if (Feature == "fma4") { HasFMA4 = true; continue; } + if (Feature == "fma") { + HasFMA = true; + continue; + } + + if (Feature == "xop") { + HasXOP = true; + continue; + } + assert(Features[i][0] == '+' && "Invalid target feature!"); X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) .Case("avx2", AVX2) @@ -1894,10 +2072,6 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. if (PointerWidth == 64) { - if (getLongWidth() == 64) { - Builder.defineMacro("_LP64"); - Builder.defineMacro("__LP64__"); - } Builder.defineMacro("__amd64__"); Builder.defineMacro("__amd64"); Builder.defineMacro("__x86_64"); @@ -2039,9 +2213,15 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasAES) Builder.defineMacro("__AES__"); + if (HasPCLMUL) + Builder.defineMacro("__PCLMUL__"); + if (HasLZCNT) Builder.defineMacro("__LZCNT__"); + if (HasRDRND) + Builder.defineMacro("__RDRND__"); + if (HasBMI) Builder.defineMacro("__BMI__"); @@ -2051,9 +2231,18 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasPOPCNT) Builder.defineMacro("__POPCNT__"); + if (HasSSE4a) + Builder.defineMacro("__SSE4A__"); + if (HasFMA4) Builder.defineMacro("__FMA4__"); + if (HasFMA) + Builder.defineMacro("__FMA__"); + + if (HasXOP) + Builder.defineMacro("__XOP__"); + // Each case falls through to the previous one here. switch (SSELevel) { case AVX2: @@ -2117,11 +2306,14 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("avx2", SSELevel >= AVX2) .Case("bmi", HasBMI) .Case("bmi2", HasBMI2) + .Case("fma", HasFMA) .Case("fma4", HasFMA4) .Case("lzcnt", HasLZCNT) + .Case("rdrnd", HasRDRND) .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon) .Case("mmx", MMX3DNowLevel >= MMX) + .Case("pclmul", HasPCLMUL) .Case("popcnt", HasPOPCNT) .Case("sse", SSELevel >= SSE1) .Case("sse2", SSELevel >= SSE2) @@ -2129,9 +2321,11 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("ssse3", SSELevel >= SSSE3) .Case("sse41", SSELevel >= SSE41) .Case("sse42", SSELevel >= SSE42) + .Case("sse4a", HasSSE4a) .Case("x86", true) .Case("x86_32", PointerWidth == 32) .Case("x86_64", PointerWidth == 64) + .Case("xop", HasXOP) .Default(false); } @@ -2227,8 +2421,8 @@ public: // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.) MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } - virtual const char *getVAListDeclaration() const { - return "typedef char* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::CharPtrBuiltinVaList; } int getEHDataRegisterNumber(unsigned RegNo) const { @@ -2266,6 +2460,18 @@ public: } // end anonymous namespace namespace { +class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> { +public: + BitrigI386TargetInfo(const std::string& triple) : + BitrigTargetInfo<X86_32TargetInfo>(triple) { + SizeType = UnsignedLong; + IntPtrType = SignedLong; + PtrDiffType = SignedLong; + } +}; +} // end anonymous namespace + +namespace { class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { public: DarwinI386TargetInfo(const std::string& triple) : @@ -2273,6 +2479,7 @@ public: LongDoubleWidth = 128; LongDoubleAlign = 128; SuitableAlign = 128; + MaxVectorAlign = 256; SizeType = UnsignedLong; IntPtrType = SignedLong; DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" @@ -2487,14 +2694,8 @@ public: MaxAtomicPromoteWidth = 128; MaxAtomicInlineWidth = 64; } - virtual const char *getVAListDeclaration() const { - return "typedef struct __va_list_tag {" - " unsigned gp_offset;" - " unsigned fp_offset;" - " void* overflow_arg_area;" - " void* reg_save_area;" - "} __va_list_tag;" - "typedef __va_list_tag __builtin_va_list[1];"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::X86_64ABIBuiltinVaList; } int getEHDataRegisterNumber(unsigned RegNo) const { @@ -2528,8 +2729,8 @@ public: WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder); Builder.defineMacro("_WIN64"); } - virtual const char *getVAListDeclaration() const { - return "typedef char* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::CharPtrBuiltinVaList; } }; } // end anonymous namespace @@ -2586,6 +2787,7 @@ public: DarwinX86_64TargetInfo(const std::string& triple) : DarwinTargetInfo<X86_64TargetInfo>(triple) { Int64Type = SignedLongLong; + MaxVectorAlign = 256; } }; } // end anonymous namespace @@ -2603,6 +2805,18 @@ public: } // end anonymous namespace namespace { +class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> { +public: + BitrigX86_64TargetInfo(const std::string& triple) + : BitrigTargetInfo<X86_64TargetInfo>(triple) { + IntMaxType = SignedLongLong; + UIntMaxType = UnsignedLongLong; + Int64Type = SignedLongLong; + } +}; +} // end anonymous namespace + +namespace { class ARMTargetInfo : public TargetInfo { // Possible FPU choices. enum FPUMode { @@ -2860,8 +3074,8 @@ public: NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin; } virtual bool isCLZForZeroUndef() const { return false; } - virtual const char *getVAListDeclaration() const { - return "typedef void* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::VoidPtrBuiltinVaList; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; @@ -3015,8 +3229,8 @@ public: HexagonTargetInfo(const std::string& triple) : TargetInfo(triple) { BigEndian = false; DescriptionString = ("e-p:32:32:32-" - "i64:64:64-i32:32:32-" - "i16:16:16-i1:32:32-a:0:0"); + "i64:64:64-i32:32:32-i16:16:16-i1:32:32" + "f64:64:64-f32:32:32-a0:0-n32"); // {} in inline assembly are packet specifiers, not assembly variant // specifiers. @@ -3041,8 +3255,8 @@ public: return Feature == "hexagon"; } - virtual const char *getVAListDeclaration() const { - return "typedef char* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::CharPtrBuiltinVaList; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; @@ -3057,6 +3271,7 @@ public: .Case("hexagonv2", "2") .Case("hexagonv3", "3") .Case("hexagonv4", "4") + .Case("hexagonv5", "5") .Default(0); } @@ -3111,6 +3326,14 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__QDSP6_ARCH__", "4"); } } + else if(CPU == "hexagonv5") { + Builder.defineMacro("__HEXAGON_V5__"); + Builder.defineMacro("__HEXAGON_ARCH__", "5"); + if(Opts.HexagonQdsp6Compat) { + Builder.defineMacro("__QDSP6_V5__"); + Builder.defineMacro("__QDSP6_ARCH__", "5"); + } + } } const char * const HexagonTargetInfo::GCCRegNames[] = { @@ -3159,7 +3382,6 @@ class SparcV8TargetInfo : public TargetInfo { public: SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { // FIXME: Support Sparc quad-precision long double? - BigEndian = false; 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"; } @@ -3200,8 +3422,8 @@ public: unsigned &NumRecords) const { // FIXME: Implement! } - virtual const char *getVAListDeclaration() const { - return "typedef void* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::VoidPtrBuiltinVaList; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; @@ -3344,9 +3566,9 @@ namespace { // FIXME: Is this really right? return ""; } - virtual const char *getVAListDeclaration() const { + virtual BuiltinVaListKind getBuiltinVaListKind() const { // FIXME: implement - return "typedef char* __builtin_va_list;"; + return TargetInfo::CharPtrBuiltinVaList; } }; @@ -3375,7 +3597,10 @@ namespace { static const unsigned TCEOpenCLAddrSpaceMap[] = { 3, // opencl_global 4, // opencl_local - 5 // opencl_constant + 5, // opencl_constant + 0, // cuda_device + 0, // cuda_constant + 0 // cuda_shared }; class TCETargetInfo : public TargetInfo{ @@ -3425,8 +3650,8 @@ namespace { virtual const char *getClobbers() const { return ""; } - virtual const char *getVAListDeclaration() const { - return "typedef void* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::VoidPtrBuiltinVaList; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const {} @@ -3441,9 +3666,15 @@ namespace { namespace { class MipsTargetInfoBase : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; std::string CPU; - bool SoftFloat; - bool SingleFloat; + bool IsMips16; + enum MipsFloatABI { + HardFloat, SingleFloat, SoftFloat + } FloatABI; + enum DspRevEnum { + NoDSP, DSP1, DSP2 + } DspRev; protected: std::string ABI; @@ -3454,7 +3685,9 @@ public: const std::string& CPUStr) : TargetInfo(triple), CPU(CPUStr), - SoftFloat(false), SingleFloat(false), + IsMips16(false), + FloatABI(HardFloat), + DspRev(NoDSP), ABI(ABIStr) {} @@ -3471,14 +3704,35 @@ public: virtual void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const { - if (SoftFloat) - Builder.defineMacro("__mips_soft_float", Twine(1)); - else if (SingleFloat) - Builder.defineMacro("__mips_single_float", Twine(1)); - else if (!SoftFloat && !SingleFloat) + switch (FloatABI) { + case HardFloat: Builder.defineMacro("__mips_hard_float", Twine(1)); - else - llvm_unreachable("Invalid float ABI for Mips."); + 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 (IsMips16) + Builder.defineMacro("__mips16", Twine(1)); + + switch (DspRev) { + default: + break; + case DSP1: + Builder.defineMacro("__mips_dsp_rev", Twine(1)); + Builder.defineMacro("__mips_dsp", Twine(1)); + break; + case DSP2: + Builder.defineMacro("__mips_dsp_rev", Twine(2)); + Builder.defineMacro("__mips_dspr2", Twine(1)); + Builder.defineMacro("__mips_dsp", Twine(1)); + break; + } Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0))); Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth())); @@ -3489,13 +3743,14 @@ public: MacroBuilder &Builder) const = 0; virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { - // FIXME: Implement! + Records = BuiltinInfo; + NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin; } virtual bool hasFeature(StringRef Feature) const { return Feature == "mips"; } - virtual const char *getVAListDeclaration() const { - return "typedef void* __builtin_va_list;"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::VoidPtrBuiltinVaList; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const { @@ -3549,7 +3804,8 @@ public: if (Name == "soft-float" || Name == "single-float" || Name == "o32" || Name == "n32" || Name == "n64" || Name == "eabi" || Name == "mips32" || Name == "mips32r2" || - Name == "mips64" || Name == "mips64r2") { + Name == "mips64" || Name == "mips64r2" || + Name == "mips16" || Name == "dsp" || Name == "dspr2") { Features[Name] = Enabled; return true; } @@ -3557,27 +3813,39 @@ public: } virtual void HandleTargetFeatures(std::vector<std::string> &Features) { - SoftFloat = false; - SingleFloat = false; + IsMips16 = false; + FloatABI = HardFloat; + DspRev = NoDSP; for (std::vector<std::string>::iterator it = Features.begin(), ie = Features.end(); it != ie; ++it) { - if (*it == "+single-float") { - SingleFloat = true; - break; - } - - if (*it == "+soft-float") { - SoftFloat = true; - // This option is front-end specific. - // Do not need to pass it to the backend. - Features.erase(it); - break; - } + if (*it == "+single-float") + FloatABI = SingleFloat; + else if (*it == "+soft-float") + FloatABI = SoftFloat; + else if (*it == "+mips16") + IsMips16 = true; + else if (*it == "+dsp") + DspRev = std::max(DspRev, DSP1); + else if (*it == "+dspr2") + DspRev = std::max(DspRev, DSP2); } + + // Remove front-end specific option. + std::vector<std::string>::iterator it = + std::find(Features.begin(), Features.end(), "+soft-float"); + if (it != Features.end()) + Features.erase(it); } }; +const Builtin::Info MipsTargetInfoBase::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/BuiltinsMips.def" +}; + class Mips32TargetInfoBase : public MipsTargetInfoBase { public: Mips32TargetInfoBase(const std::string& triple) : @@ -3868,8 +4136,8 @@ public: virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { } - virtual const char *getVAListDeclaration() const { - return "typedef int __builtin_va_list[4];"; + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::PNaClABIBuiltinVaList; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; @@ -3926,6 +4194,10 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new FreeBSDTargetInfo<ARMTargetInfo>(T); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<ARMTargetInfo>(T); + case llvm::Triple::OpenBSD: + return new OpenBSDTargetInfo<ARMTargetInfo>(T); + case llvm::Triple::Bitrig: + return new BitrigTargetInfo<ARMTargetInfo>(T); case llvm::Triple::RTEMS: return new RTEMSTargetInfo<ARMTargetInfo>(T); default: @@ -3973,6 +4245,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new FreeBSDTargetInfo<Mips64EBTargetInfo>(T); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<Mips64EBTargetInfo>(T); + case llvm::Triple::OpenBSD: + return new OpenBSDTargetInfo<Mips64EBTargetInfo>(T); default: return new Mips64EBTargetInfo(T); } @@ -3987,6 +4261,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new FreeBSDTargetInfo<Mips64ELTargetInfo>(T); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<Mips64ELTargetInfo>(T); + case llvm::Triple::OpenBSD: + return new OpenBSDTargetInfo<Mips64ELTargetInfo>(T); default: return new Mips64ELTargetInfo(T); } @@ -4009,6 +4285,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new FreeBSDTargetInfo<PPC32TargetInfo>(T); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<PPC32TargetInfo>(T); + case llvm::Triple::OpenBSD: + return new OpenBSDTargetInfo<PPC32TargetInfo>(T); case llvm::Triple::RTEMS: return new RTEMSTargetInfo<PPC32TargetInfo>(T); default: @@ -4031,10 +4309,10 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new PPC64TargetInfo(T); } - case llvm::Triple::ptx32: - return new PTX32TargetInfo(T); - case llvm::Triple::ptx64: - return new PTX64TargetInfo(T); + case llvm::Triple::nvptx: + return new NVPTX32TargetInfo(T); + case llvm::Triple::nvptx64: + return new NVPTX64TargetInfo(T); case llvm::Triple::mblaze: return new MBlazeTargetInfo(T); @@ -4049,6 +4327,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new SolarisSparcV8TargetInfo(T); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<SparcV8TargetInfo>(T); + case llvm::Triple::OpenBSD: + return new OpenBSDTargetInfo<SparcV8TargetInfo>(T); case llvm::Triple::RTEMS: return new RTEMSTargetInfo<SparcV8TargetInfo>(T); default: @@ -4077,6 +4357,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new NetBSDI386TargetInfo(T); case llvm::Triple::OpenBSD: return new OpenBSDI386TargetInfo(T); + case llvm::Triple::Bitrig: + return new BitrigI386TargetInfo(T); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<X86_32TargetInfo>(T); case llvm::Triple::Minix: @@ -4112,6 +4394,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new NetBSDTargetInfo<X86_64TargetInfo>(T); case llvm::Triple::OpenBSD: return new OpenBSDX86_64TargetInfo(T); + case llvm::Triple::Bitrig: + return new BitrigX86_64TargetInfo(T); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<X86_64TargetInfo>(T); case llvm::Triple::Solaris: diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp index 8cb2386..9daa30a 100644 --- a/lib/Basic/Version.cpp +++ b/lib/Basic/Version.cpp @@ -32,7 +32,7 @@ std::string getClangRepositoryPath() { // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/branches/release_31/lib/Basic/Version.cpp $"); + static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/trunk/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); @@ -136,8 +136,7 @@ std::string getClangFullCPPVersion() { #ifdef CLANG_VENDOR OS << CLANG_VENDOR; #endif - OS << "Clang " CLANG_VERSION_STRING " (" - << getClangFullRepositoryVersion() << ')'; + OS << "Clang " CLANG_VERSION_STRING " " << getClangFullRepositoryVersion(); return OS.str(); } diff --git a/lib/Basic/VersionTuple.cpp b/lib/Basic/VersionTuple.cpp index 77aad39..4f479d0 100644 --- a/lib/Basic/VersionTuple.cpp +++ b/lib/Basic/VersionTuple.cpp @@ -34,3 +34,55 @@ raw_ostream& clang::operator<<(raw_ostream &Out, Out << '.' << *Subminor; return Out; } + +static bool parseInt(StringRef &input, unsigned &value) { + assert(value == 0); + if (input.empty()) return true; + + char next = input[0]; + input = input.substr(1); + if (next < '0' || next > '9') return true; + value = (unsigned) (next - '0'); + + while (!input.empty()) { + next = input[0]; + if (next < '0' || next > '9') return false; + input = input.substr(1); + value = value * 10 + (unsigned) (next - '0'); + } + + return false; +} + +bool VersionTuple::tryParse(StringRef input) { + unsigned major = 0, minor = 0, micro = 0; + + // Parse the major version, [0-9]+ + if (parseInt(input, major)) return true; + + if (input.empty()) { + *this = VersionTuple(major); + return false; + } + + // If we're not done, parse the minor version, \.[0-9]+ + if (input[0] != '.') return true; + input = input.substr(1); + if (parseInt(input, minor)) return true; + + if (input.empty()) { + *this = VersionTuple(major, minor); + return false; + } + + // If we're not done, parse the micro version, \.[0-9]+ + if (input[0] != '.') return true; + input = input.substr(1); + if (parseInt(input, micro)) return true; + + // If we have characters left over, it's an error. + if (!input.empty()) return true; + + *this = VersionTuple(major, minor, micro); + return false; +} |