diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Builtins.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/ConvertUTF.c | 143 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp | 126 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp | 229 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/FileManager.cpp | 27 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp | 43 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Module.cpp | 274 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp | 4 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp | 144 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp | 5 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Targets.cpp | 956 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Version.cpp | 58 |
14 files changed, 1391 insertions, 623 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp index 7bdcdc6..c78a292 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp @@ -15,6 +15,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/LangOptions.h" +#include "llvm/ADT/SmallVector.h" using namespace clang; static const Builtin::Info BuiltinInfo[] = { diff --git a/contrib/llvm/tools/clang/lib/Basic/ConvertUTF.c b/contrib/llvm/tools/clang/lib/Basic/ConvertUTF.c index 124e386..e197003 100644 --- a/contrib/llvm/tools/clang/lib/Basic/ConvertUTF.c +++ b/contrib/llvm/tools/clang/lib/Basic/ConvertUTF.c @@ -339,67 +339,6 @@ ConversionResult ConvertUTF32toUTF8 ( return result; } -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF32 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF32* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (!isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; - case 4: ch += *source++; ch <<= 6; - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up the source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_LEGAL_UTF32) { - /* - * UTF-16 surrogate values are illegal in UTF-32, and anything - * over Plane 17 (> 0x10FFFF) is illegal. - */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = ch; - } - } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ - result = sourceIllegal; - *target++ = UNI_REPLACEMENT_CHAR; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} #endif /* --------------------------------------------------------------------- */ @@ -448,7 +387,7 @@ static Boolean isLegalUTF8(const UTF8 *source, int length) { */ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { int length = trailingBytesForUTF8[*source]+1; - if (source+length > sourceEnd) { + if (length > sourceEnd - source) { return false; } return isLegalUTF8(source, length); @@ -456,6 +395,22 @@ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { /* --------------------------------------------------------------------- */ +/* + * Exported function to return whether a UTF-8 string is legal or not. + * This is not used here; it's just exported. + */ +Boolean isLegalUTF8String(const UTF8 *source, const UTF8 *sourceEnd) { + while (source != sourceEnd) { + int length = trailingBytesForUTF8[*source] + 1; + if (length > sourceEnd - source || !isLegalUTF8(source, length)) + return false; + source += length; + } + return true; +} + +/* --------------------------------------------------------------------- */ + ConversionResult ConvertUTF8toUTF16 ( const UTF8** sourceStart, const UTF8* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { @@ -465,7 +420,7 @@ ConversionResult ConvertUTF8toUTF16 ( while (source < sourceEnd) { UTF32 ch = 0; unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { + if (extraBytesToRead >= sourceEnd - source) { result = sourceExhausted; break; } /* Do this check whether lenient or strict */ @@ -527,6 +482,68 @@ ConversionResult ConvertUTF8toUTF16 ( return result; } +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF8toUTF32 ( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF8* source = *sourceStart; + UTF32* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (extraBytesToRead >= sourceEnd - source) { + result = sourceExhausted; break; + } + /* Do this check whether lenient or strict */ + if (!isLegalUTF8(source, extraBytesToRead+1)) { + result = sourceIllegal; + break; + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 5: ch += *source++; ch <<= 6; + case 4: ch += *source++; ch <<= 6; + case 3: ch += *source++; ch <<= 6; + case 2: ch += *source++; ch <<= 6; + case 1: ch += *source++; ch <<= 6; + case 0: ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (target >= targetEnd) { + source -= (extraBytesToRead+1); /* Back up the source pointer! */ + result = targetExhausted; break; + } + if (ch <= UNI_MAX_LEGAL_UTF32) { + /* + * UTF-16 surrogate values are illegal in UTF-32, and anything + * over Plane 17 (> 0x10FFFF) is illegal. + */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + if (flags == strictConversion) { + source -= (extraBytesToRead+1); /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + *target++ = ch; + } + } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ + result = sourceIllegal; + *target++ = UNI_REPLACEMENT_CHAR; + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + /* --------------------------------------------------------------------- Note A. diff --git a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp index e5f3901..f7d5d87 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp @@ -14,7 +14,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/PartialDiagnostic.h" -#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/CrashRecoveryContext.h" @@ -27,14 +27,14 @@ static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, unsigned NumPrevArgs, SmallVectorImpl<char> &Output, void *Cookie, - SmallVectorImpl<intptr_t> &QualTypeVals) { + ArrayRef<intptr_t> QualTypeVals) { const char *Str = "<can't format argument>"; Output.append(Str, Str+strlen(Str)); } DiagnosticsEngine::DiagnosticsEngine( - const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &diags, + const IntrusiveRefCntPtr<DiagnosticIDs> &diags, DiagnosticConsumer *client, bool ShouldOwnClient) : Diags(diags), Client(client), OwnsDiagClient(ShouldOwnClient), SourceMgr(0) { @@ -53,6 +53,7 @@ DiagnosticsEngine::DiagnosticsEngine( ErrorLimit = 0; TemplateBacktraceLimit = 0; + ConstexprBacktraceLimit = 0; Reset(); } @@ -118,7 +119,7 @@ void DiagnosticsEngine::Reset() { } void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1, - StringRef Arg2) { + StringRef Arg2) { if (DelayedDiagID) return; @@ -161,7 +162,7 @@ DiagnosticsEngine::GetDiagStatePointForLoc(SourceLocation L) const { /// \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) { + SourceLocation L) { assert(Diag < diag::DIAG_UPPER_LIMIT && "Can only map builtin diagnostics"); assert((Diags->isBuiltinWarningOrExtension(Diag) || @@ -169,18 +170,16 @@ void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map, "Cannot map errors into warnings!"); assert(!DiagStatePoints.empty()); - bool isPragma = L.isValid(); FullSourceLoc Loc(L, *SourceMgr); FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc; - DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make( - Map, /*IsUser=*/true, isPragma); - - // If this is a pragma mapping, then set the diagnostic mapping flags so that - // we override command line options. - if (isPragma) { - MappingInfo.setNoWarningAsError(true); - MappingInfo.setNoErrorAsFatal(true); + // Don't allow a mapping to a warning override an error/fatal mapping. + if (Map == diag::MAP_WARNING) { + DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag); + if (Info.getMapping() == diag::MAP_ERROR || + Info.getMapping() == diag::MAP_FATAL) + Map = Info.getMapping(); } + DiagnosticMappingInfo MappingInfo = makeMappingInfo(Map, L); // Common case; setting all the diagnostics of a group in one place. if (Loc.isInvalid() || Loc == LastStateChangePos) { @@ -244,6 +243,24 @@ bool DiagnosticsEngine::setDiagnosticGroupMapping( return false; } +void DiagnosticsEngine::setDiagnosticWarningAsError(diag::kind Diag, + bool Enabled) { + // If we are enabling this feature, just set the diagnostic mappings to map to + // errors. + if (Enabled) + setDiagnosticMapping(Diag, diag::MAP_ERROR, SourceLocation()); + + // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and + // potentially downgrade anything already mapped to be a warning. + DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag); + + if (Info.getMapping() == diag::MAP_ERROR || + Info.getMapping() == diag::MAP_FATAL) + Info.setMapping(diag::MAP_WARNING); + + Info.setNoWarningAsError(true); +} + bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled) { // If we are enabling this feature, just set the diagnostic mappings to map to @@ -274,6 +291,23 @@ bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group, return false; } +void DiagnosticsEngine::setDiagnosticErrorAsFatal(diag::kind Diag, + bool Enabled) { + // If we are enabling this feature, just set the diagnostic mappings to map to + // errors. + if (Enabled) + setDiagnosticMapping(Diag, diag::MAP_FATAL, SourceLocation()); + + // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and + // potentially downgrade anything already mapped to be a warning. + DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag); + + if (Info.getMapping() == diag::MAP_FATAL) + Info.setMapping(diag::MAP_ERROR); + + Info.setNoErrorAsFatal(true); +} + bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled) { // If we are enabling this feature, just set the diagnostic mappings to map to @@ -303,6 +337,18 @@ bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group, return false; } +void DiagnosticsEngine::setMappingToAllDiagnostics(diag::Mapping Map, + SourceLocation Loc) { + // Get all the diagnostics. + llvm::SmallVector<diag::kind, 64> AllDiags; + Diags->getAllDiagnostics(AllDiags); + + // Set the mapping. + for (unsigned i = 0, e = AllDiags.size(); i != e; ++i) + if (Diags->isBuiltinWarningOrExtension(AllDiags[i])) + setDiagnosticMapping(AllDiags[i], Map, Loc); +} + void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!"); @@ -311,7 +357,7 @@ void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { NumDiagArgs = 0; NumDiagRanges = storedDiag.range_size(); - assert(NumDiagRanges < sizeof(DiagRanges)/sizeof(DiagRanges[0]) && + assert(NumDiagRanges < DiagnosticsEngine::MaxRanges && "Too many arguments to diagnostic!"); unsigned i = 0; for (StoredDiagnostic::range_iterator @@ -319,14 +365,13 @@ void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { RE = storedDiag.range_end(); RI != RE; ++RI) DiagRanges[i++] = *RI; - NumFixItHints = storedDiag.fixit_size(); - assert(NumFixItHints < DiagnosticsEngine::MaxFixItHints && - "Too many fix-it hints!"); - i = 0; + assert(NumDiagRanges < DiagnosticsEngine::MaxFixItHints && + "Too many arguments to diagnostic!"); + NumDiagFixItHints = 0; for (StoredDiagnostic::fixit_iterator FI = storedDiag.fixit_begin(), FE = storedDiag.fixit_end(); FI != FE; ++FI) - FixItHints[i++] = *FI; + DiagFixItHints[NumDiagFixItHints++] = *FI; assert(Client && "DiagnosticConsumer not set!"); Level DiagLevel = storedDiag.getLevel(); @@ -340,35 +385,18 @@ void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { CurDiagID = ~0U; } -void DiagnosticBuilder::FlushCounts() { - DiagObj->NumDiagArgs = NumArgs; - DiagObj->NumDiagRanges = NumRanges; - DiagObj->NumFixItHints = NumFixItHints; -} - -bool DiagnosticBuilder::Emit() { - // If DiagObj is null, then its soul was stolen by the copy ctor - // or the user called Emit(). - if (DiagObj == 0) return false; - - // When emitting diagnostics, we set the final argument count into - // the DiagnosticsEngine object. - FlushCounts(); - +bool DiagnosticsEngine::EmitCurrentDiagnostic() { // Process the diagnostic, sending the accumulated information to the // DiagnosticConsumer. - bool Emitted = DiagObj->ProcessDiag(); + bool Emitted = ProcessDiag(); // Clear out the current diagnostic object. - unsigned DiagID = DiagObj->CurDiagID; - DiagObj->Clear(); + unsigned DiagID = CurDiagID; + Clear(); // If there was a delayed diagnostic, emit it now. - if (DiagObj->DelayedDiagID && DiagObj->DelayedDiagID != DiagID) - DiagObj->ReportDelayed(); - - // This diagnostic is dead. - DiagObj = 0; + if (DelayedDiagID && DelayedDiagID != DiagID) + ReportDelayed(); return Emitted; } @@ -802,7 +830,7 @@ StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, "Valid source location without setting a source manager for diagnostic"); if (Info.getLocation().isValid()) Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager()); - llvm::SmallString<64> Message; + SmallString<64> Message; Info.FormatDiagnostic(Message); this->Message.assign(Message.begin(), Message.end()); @@ -833,6 +861,8 @@ StoredDiagnostic::~StoredDiagnostic() { } /// reported by DiagnosticsEngine. bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; } +void IgnoringDiagConsumer::anchor() { } + PartialDiagnostic::StorageAllocator::StorageAllocator() { for (unsigned I = 0; I != NumCached; ++I) FreeList[I] = Cached + I; @@ -840,7 +870,9 @@ PartialDiagnostic::StorageAllocator::StorageAllocator() { } PartialDiagnostic::StorageAllocator::~StorageAllocator() { - // Don't assert if we are in a CrashRecovery context, as this - // invariant may be invalidated during a crash. - assert((NumFreeListEntries == NumCached || llvm::CrashRecoveryContext::isRecoveringFromCrash()) && "A partial is on the lamb"); + // Don't assert if we are in a CrashRecovery context, as this invariant may + // be invalidated during a crash. + assert((NumFreeListEntries == NumCached || + llvm::CrashRecoveryContext::isRecoveringFromCrash()) && + "A partial is on the lamb"); } diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp index 9481287..8c33a96 100644 --- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp @@ -11,16 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "clang/AST/ASTDiagnostic.h" -#include "clang/Analysis/AnalysisDiagnostic.h" #include "clang/Basic/DiagnosticIDs.h" +#include "clang/Basic/AllDiagnostics.h" #include "clang/Basic/DiagnosticCategories.h" #include "clang/Basic/SourceManager.h" -#include "clang/Driver/DriverDiagnostic.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Lex/LexDiagnostic.h" -#include "clang/Parse/ParseDiagnostic.h" -#include "clang/Sema/SemaDiagnostic.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ErrorHandling.h" @@ -51,107 +45,49 @@ struct StaticDiagInfoRec { unsigned WarnShowInSystemHeader : 1; unsigned Category : 5; - uint8_t NameLen; - uint8_t OptionGroupLen; + uint16_t OptionGroupIndex; uint16_t DescriptionLen; - uint16_t BriefExplanationLen; - uint16_t FullExplanationLen; - - const char *NameStr; - const char *OptionGroupStr; - const char *DescriptionStr; - const char *BriefExplanationStr; - const char *FullExplanationStr; - StringRef getName() const { - return StringRef(NameStr, NameLen); - } - StringRef getOptionGroup() const { - return StringRef(OptionGroupStr, OptionGroupLen); + unsigned getOptionGroupIndex() const { + return OptionGroupIndex; } StringRef getDescription() const { return StringRef(DescriptionStr, DescriptionLen); } - StringRef getBriefExplanation() const { - return StringRef(BriefExplanationStr, BriefExplanationLen); - } - StringRef getFullExplanation() const { - return StringRef(FullExplanationStr, FullExplanationLen); - } bool operator<(const StaticDiagInfoRec &RHS) const { return DiagID < RHS.DiagID; } }; -struct StaticDiagNameIndexRec { - const char *NameStr; - unsigned short DiagID; - uint8_t NameLen; - - StringRef getName() const { - return StringRef(NameStr, NameLen); - } - - bool operator<(const StaticDiagNameIndexRec &RHS) const { - return getName() < RHS.getName(); - } - - bool operator==(const StaticDiagNameIndexRec &RHS) const { - return getName() == RHS.getName(); - } -}; - -template <size_t SizeOfStr, typename FieldType> -class StringSizerHelper { - char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1]; -public: - enum { Size = SizeOfStr }; -}; - } // namespace anonymous -#define STR_SIZE(str, fieldTy) StringSizerHelper<sizeof(str)-1, fieldTy>::Size - static const StaticDiagInfoRec StaticDiagInfo[] = { #define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER, \ - CATEGORY,BRIEF,FULL) \ + CATEGORY) \ { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS, \ - NOWERROR, SHOWINSYSHEADER, CATEGORY, \ - STR_SIZE(#ENUM, uint8_t), STR_SIZE(GROUP, uint8_t), \ - STR_SIZE(DESC, uint16_t), STR_SIZE(BRIEF, uint16_t), \ - STR_SIZE(FULL, uint16_t), \ - #ENUM, GROUP, DESC, BRIEF, FULL }, + NOWERROR, SHOWINSYSHEADER, CATEGORY, GROUP, \ + STR_SIZE(DESC, uint16_t), DESC }, #include "clang/Basic/DiagnosticCommonKinds.inc" #include "clang/Basic/DiagnosticDriverKinds.inc" #include "clang/Basic/DiagnosticFrontendKinds.inc" +#include "clang/Basic/DiagnosticSerializationKinds.inc" #include "clang/Basic/DiagnosticLexKinds.inc" #include "clang/Basic/DiagnosticParseKinds.inc" #include "clang/Basic/DiagnosticASTKinds.inc" #include "clang/Basic/DiagnosticSemaKinds.inc" #include "clang/Basic/DiagnosticAnalysisKinds.inc" #undef DIAG - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; static const unsigned StaticDiagInfoSize = sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1; -/// To be sorted before first use (since it's splitted among multiple files) -static const StaticDiagNameIndexRec StaticDiagNameIndex[] = { -#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) }, -#include "clang/Basic/DiagnosticIndexName.inc" -#undef DIAG_NAME_INDEX - { 0, 0, 0 } -}; - -static const unsigned StaticDiagNameIndexSize = - sizeof(StaticDiagNameIndex)/sizeof(StaticDiagNameIndex[0])-1; - /// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID, /// or null if the ID is invalid. static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) { @@ -173,7 +109,7 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) { // Search the diagnostic table with a binary search. StaticDiagInfoRec Find = { static_cast<unsigned short>(DiagID), - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const StaticDiagInfoRec *Found = std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find); @@ -207,15 +143,6 @@ static DiagnosticMappingInfo GetDefaultDiagMappingInfo(unsigned DiagID) { return Info; } -/// getWarningOptionForDiag - Return the lowest-level warning option that -/// enables the specified diagnostic. If there is no -Wfoo flag that controls -/// the diagnostic, this returns null. -StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) { - if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->getOptionGroup(); - return StringRef(); -} - /// getCategoryNumberForDiag - Return the category number that a specified /// DiagID belongs to, or 0 if no category. unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) { @@ -295,50 +222,6 @@ DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) { return SFINAE_Report; } -/// getName - Given a diagnostic ID, return its name -StringRef DiagnosticIDs::getName(unsigned DiagID) { - if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->getName(); - return StringRef(); -} - -/// getIdFromName - Given a diagnostic name, return its ID, or 0 -unsigned DiagnosticIDs::getIdFromName(StringRef Name) { - const StaticDiagNameIndexRec *StaticDiagNameIndexEnd = - StaticDiagNameIndex + StaticDiagNameIndexSize; - - if (Name.empty()) { return diag::DIAG_UPPER_LIMIT; } - - assert(Name.size() == static_cast<uint8_t>(Name.size()) && - "Name is too long"); - StaticDiagNameIndexRec Find = { Name.data(), 0, - static_cast<uint8_t>(Name.size()) }; - - const StaticDiagNameIndexRec *Found = - std::lower_bound( StaticDiagNameIndex, StaticDiagNameIndexEnd, Find); - if (Found == StaticDiagNameIndexEnd || - Found->getName() != Name) - return diag::DIAG_UPPER_LIMIT; - - return Found->DiagID; -} - -/// getBriefExplanation - Given a diagnostic ID, return a brief explanation -/// of the issue -StringRef DiagnosticIDs::getBriefExplanation(unsigned DiagID) { - if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->getBriefExplanation(); - return StringRef(); -} - -/// getFullExplanation - Given a diagnostic ID, return a full explanation -/// of the issue -StringRef DiagnosticIDs::getFullExplanation(unsigned DiagID) { - if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->getFullExplanation(); - return StringRef(); -} - /// getBuiltinDiagClass - Return the class field of the diagnostic. /// static unsigned getBuiltinDiagClass(unsigned DiagID) { @@ -348,35 +231,6 @@ static unsigned getBuiltinDiagClass(unsigned DiagID) { } //===----------------------------------------------------------------------===// -// diag_iterator -//===----------------------------------------------------------------------===// - -llvm::StringRef DiagnosticIDs::diag_iterator::getDiagName() const { - return static_cast<const StaticDiagNameIndexRec*>(impl)->getName(); -} - -unsigned DiagnosticIDs::diag_iterator::getDiagID() const { - return static_cast<const StaticDiagNameIndexRec*>(impl)->DiagID; -} - -DiagnosticIDs::diag_iterator &DiagnosticIDs::diag_iterator::operator++() { - const StaticDiagNameIndexRec* ptr = - static_cast<const StaticDiagNameIndexRec*>(impl);; - ++ptr; - impl = ptr; - return *this; -} - -DiagnosticIDs::diag_iterator DiagnosticIDs::diags_begin() { - return DiagnosticIDs::diag_iterator(StaticDiagNameIndex); -} - -DiagnosticIDs::diag_iterator DiagnosticIDs::diags_end() { - return DiagnosticIDs::diag_iterator(StaticDiagNameIndex + - StaticDiagNameIndexSize); -} - -//===----------------------------------------------------------------------===// // Custom Diagnostic information //===----------------------------------------------------------------------===// @@ -530,7 +384,6 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, (diag::kind)DiagID); switch (MappingInfo.getMapping()) { - default: llvm_unreachable("Unknown mapping!"); case diag::MAP_IGNORE: Result = DiagnosticIDs::Ignored; break; @@ -553,7 +406,7 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, // Ignore -pedantic diagnostics inside __extension__ blocks. // (The diagnostics controlled by -pedantic are the extension diagnostics // that are not enabled by default.) - bool EnabledByDefault; + bool EnabledByDefault = false; bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault); if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault) return DiagnosticIDs::Ignored; @@ -648,6 +501,15 @@ static bool WarningOptionCompare(const WarningOption &LHS, return LHS.getName() < RHS.getName(); } +/// getWarningOptionForDiag - Return the lowest-level warning option that +/// enables the specified diagnostic. If there is no -Wfoo flag that controls +/// the diagnostic, this returns null. +StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) { + if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) + return OptionTable[Info->getOptionGroupIndex()].getName(); + return StringRef(); +} + void DiagnosticIDs::getDiagnosticsInGroup( const WarningOption *Group, llvm::SmallVectorImpl<diag::kind> &Diags) const @@ -681,6 +543,35 @@ bool DiagnosticIDs::getDiagnosticsInGroup( return false; } +void DiagnosticIDs::getAllDiagnostics( + llvm::SmallVectorImpl<diag::kind> &Diags) const { + for (unsigned i = 0; i != StaticDiagInfoSize; ++i) + Diags.push_back(StaticDiagInfo[i].DiagID); +} + +StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) { + StringRef Best; + unsigned BestDistance = Group.size() + 1; // Sanity threshold. + for (const WarningOption *i = OptionTable, *e = OptionTable + OptionTableSize; + i != e; ++i) { + // Don't suggest ignored warning flags. + if (!i->Members && !i->SubGroups) + continue; + + unsigned Distance = i->getName().edit_distance(Group, true, BestDistance); + if (Distance == BestDistance) { + // Two matches with the same distance, don't prefer one over the other. + Best = ""; + } else if (Distance < BestDistance) { + // This is a better match. + Best = i->getName(); + BestDistance = Distance; + } + } + + return Best; +} + /// ProcessDiag - This is the method used to report a diagnostic that is /// finally fully formed. bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { @@ -766,19 +657,6 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { } } - // If we have any Fix-Its, make sure that all of the Fix-Its point into - // source locations that aren't macro expansions. If any point into macro - // expansions, remove all of the Fix-Its. - for (unsigned I = 0, N = Diag.NumFixItHints; I != N; ++I) { - const FixItHint &FixIt = Diag.FixItHints[I]; - if (FixIt.RemoveRange.isInvalid() || - FixIt.RemoveRange.getBegin().isMacroID() || - FixIt.RemoveRange.getEnd().isMacroID()) { - Diag.NumFixItHints = 0; - break; - } - } - // Finally, report it. Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info); if (Diag.Client->IncludeInDiagnosticCounts()) { @@ -806,9 +684,14 @@ bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const { return false; // Currently we consider all ARC errors as recoverable. - if (getCategoryNumberForDiag(DiagID) == - diag::DiagCat_Automatic_Reference_Counting_Issue) + if (isARCDiagnostic(DiagID)) return false; return true; } + +bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) { + unsigned cat = getCategoryNumberForDiag(DiagID); + return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC "); +} + diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp index c1f715e..fd6d334 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp @@ -20,13 +20,12 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemStatCache.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" #include "llvm/Support/system_error.h" -#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" #include <map> #include <set> #include <string> @@ -106,8 +105,8 @@ public: FileEntry &getFile(const char *Name, const struct stat & /*StatBuf*/) { std::string FullPath(GetFullPath(Name)); - // LowercaseString because Windows filesystem is case insensitive. - FullPath = llvm::LowercaseString(FullPath); + // Lowercase string because Windows filesystem is case insensitive. + FullPath = StringRef(FullPath).lower(); return UniqueFiles.GetOrCreateValue(FullPath).getValue(); } @@ -266,6 +265,12 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { /// const DirectoryEntry *FileManager::getDirectory(StringRef DirName, bool CacheFailure) { + // stat doesn't like trailing separators. + // At least, on Win32 MSVCRT, stat() cannot strip trailing '/'. + // (though it can strip '\\') + if (DirName.size() > 1 && llvm::sys::path::is_separator(DirName.back())) + DirName = DirName.substr(0, DirName.size()-1); + ++NumDirLookups; llvm::StringMapEntry<DirectoryEntry *> &NamedDirEnt = SeenDirEntries.GetOrCreateValue(DirName); @@ -472,14 +477,14 @@ void FileManager::FixupRelativePath(SmallVectorImpl<char> &path) const { || llvm::sys::path::is_absolute(pathRef)) return; - llvm::SmallString<128> NewPath(FileSystemOpts.WorkingDir); + SmallString<128> NewPath(FileSystemOpts.WorkingDir); llvm::sys::path::append(NewPath, pathRef); path = NewPath; } llvm::MemoryBuffer *FileManager:: getBufferForFile(const FileEntry *Entry, std::string *ErrorStr) { - llvm::OwningPtr<llvm::MemoryBuffer> Result; + OwningPtr<llvm::MemoryBuffer> Result; llvm::error_code ec; const char *Filename = Entry->getName(); @@ -504,7 +509,7 @@ getBufferForFile(const FileEntry *Entry, std::string *ErrorStr) { return Result.take(); } - llvm::SmallString<128> FilePath(Entry->getName()); + SmallString<128> FilePath(Entry->getName()); FixupRelativePath(FilePath); ec = llvm::MemoryBuffer::getFile(FilePath.str(), Result, Entry->getSize()); if (ec && ErrorStr) @@ -514,7 +519,7 @@ getBufferForFile(const FileEntry *Entry, std::string *ErrorStr) { llvm::MemoryBuffer *FileManager:: getBufferForFile(StringRef Filename, std::string *ErrorStr) { - llvm::OwningPtr<llvm::MemoryBuffer> Result; + OwningPtr<llvm::MemoryBuffer> Result; llvm::error_code ec; if (FileSystemOpts.WorkingDir.empty()) { ec = llvm::MemoryBuffer::getFile(Filename, Result); @@ -523,7 +528,7 @@ getBufferForFile(StringRef Filename, std::string *ErrorStr) { return Result.take(); } - llvm::SmallString<128> FilePath(Filename); + SmallString<128> FilePath(Filename); FixupRelativePath(FilePath); ec = llvm::MemoryBuffer::getFile(FilePath.c_str(), Result); if (ec && ErrorStr) @@ -544,7 +549,7 @@ bool FileManager::getStatValue(const char *Path, struct stat &StatBuf, return FileSystemStatCache::get(Path, StatBuf, FileDescriptor, StatCache.get()); - llvm::SmallString<128> FilePath(Path); + SmallString<128> FilePath(Path); FixupRelativePath(FilePath); return FileSystemStatCache::get(FilePath.c_str(), StatBuf, FileDescriptor, @@ -553,7 +558,7 @@ bool FileManager::getStatValue(const char *Path, struct stat &StatBuf, bool FileManager::getNoncachedStatValue(StringRef Path, struct stat &StatBuf) { - llvm::SmallString<128> FilePath(Path); + SmallString<128> FilePath(Path); FixupRelativePath(FilePath); return ::stat(FilePath.c_str(), &StatBuf) != 0; diff --git a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp index c8b07af..875d397 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp @@ -28,6 +28,8 @@ using namespace clang; #define S_ISDIR(s) ((_S_IFDIR & s) !=0) #endif +void FileSystemStatCache::anchor() { } + /// FileSystemStatCache::get - Get the 'stat' information for the specified /// path, using the cache to accelerate it if possible. This returns true if /// the path does not exist or false if it exists. diff --git a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp index 38f09a0..43899f0 100644 --- a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp @@ -16,9 +16,10 @@ #include "clang/Basic/LangOptions.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/ErrorHandling.h" #include <cstdio> using namespace clang; @@ -37,7 +38,10 @@ IdentifierInfo::IdentifierInfo() { IsCPPOperatorKeyword = false; NeedsHandleIdentifier = false; IsFromAST = false; + ChangedAfterLoad = false; RevertedTokenID = false; + OutOfDate = false; + IsModulesImport = false; FETokenInfo = 0; Entry = 0; } @@ -74,6 +78,10 @@ IdentifierTable::IdentifierTable(const LangOptions &LangOpts, // Populate the identifier table with info about keywords for the current // language. AddKeywords(LangOpts); + + + // Add the '_experimental_modules_import' contextual keyword. + get("__experimental_modules_import").setModulesImport(true); } //===----------------------------------------------------------------------===// @@ -93,7 +101,7 @@ namespace { KEYNOCXX = 0x80, KEYBORLAND = 0x100, KEYOPENCL = 0x200, - KEYC1X = 0x400, + KEYC11 = 0x400, KEYARC = 0x800, KEYALL = 0x0fff }; @@ -105,7 +113,7 @@ namespace { /// /// The C90/C99/CPP/CPP0x flags are set to 3 if the token is a keyword in a /// future language standard, set to 2 if the token should be enabled in the -/// specified langauge, set to 1 if it is an extension in the specified +/// specified language, set to 1 if it is an extension in the specified /// language, and set to 0 if disabled in the specified language. static void AddKeyword(StringRef Keyword, tok::TokenKind TokenCode, unsigned Flags, @@ -122,8 +130,10 @@ static void AddKeyword(StringRef Keyword, else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2; else if (LangOpts.OpenCL && (Flags & KEYOPENCL)) AddResult = 2; else if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) AddResult = 2; - else if (LangOpts.C1X && (Flags & KEYC1X)) AddResult = 2; - else if (LangOpts.ObjCAutoRefCount && (Flags & KEYARC)) AddResult = 2; + else if (LangOpts.C11 && (Flags & KEYC11)) AddResult = 2; + // We treat bridge casts as objective-C keywords so we can warn on them + // in non-arc mode. + else if (LangOpts.ObjC2 && (Flags & KEYARC)) AddResult = 2; else if (LangOpts.CPlusPlus && (Flags & KEYCXX0X)) AddResult = 3; // Don't add this keyword if disabled in this language. @@ -212,7 +222,7 @@ tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const { CASE( 6, 'i', 'n', ifndef); CASE( 6, 'i', 'p', import); CASE( 6, 'p', 'a', pragma); - + CASE( 7, 'd', 'f', defined); CASE( 7, 'i', 'c', include); CASE( 7, 'w', 'r', warning); @@ -220,8 +230,11 @@ tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const { CASE( 8, 'u', 'a', unassert); CASE(12, 'i', 'c', include_next); + CASE(14, '_', 'p', __public_macro); + + CASE(15, '_', 'p', __private_macro); + CASE(16, '_', 'i', __include_macros); - CASE(16, '_', 'e', __export_macro__); #undef CASE #undef HASH } @@ -347,7 +360,7 @@ StringRef Selector::getNameForSlot(unsigned int argIndex) const { } std::string MultiKeywordSelector::getName() const { - llvm::SmallString<256> Str; + SmallString<256> Str; llvm::raw_svector_ostream OS(Str); for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) { if (*I) @@ -445,6 +458,18 @@ static SelectorTableImpl &getSelectorTableImpl(void *P) { return *static_cast<SelectorTableImpl*>(P); } +/*static*/ Selector +SelectorTable::constructSetterName(IdentifierTable &Idents, + SelectorTable &SelTable, + const IdentifierInfo *Name) { + SmallString<100> SelectorName; + SelectorName = "set"; + SelectorName += Name->getName(); + SelectorName[3] = toupper(SelectorName[3]); + IdentifierInfo *SetterName = &Idents.get(SelectorName); + return SelTable.getUnarySelector(SetterName); +} + size_t SelectorTable::getTotalMemory() const { SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl); return SelTabImpl.Allocator.getTotalMemory(); @@ -495,5 +520,5 @@ const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) { #include "clang/Basic/OperatorKinds.def" } - return 0; + llvm_unreachable("Invalid OverloadedOperatorKind!"); } diff --git a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp index 5f479db..991992a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp @@ -26,5 +26,7 @@ void LangOptions::resetNonModularOptions() { #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ Name = Default; #include "clang/Basic/LangOptions.def" + + CurrentModule.clear(); } diff --git a/contrib/llvm/tools/clang/lib/Basic/Module.cpp b/contrib/llvm/tools/clang/lib/Basic/Module.cpp new file mode 100644 index 0000000..6348840 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Basic/Module.cpp @@ -0,0 +1,274 @@ +//===--- Module.h - Describe a module ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the Module class, which describes a module in the source +// code. +// +//===----------------------------------------------------------------------===// +#include "clang/Basic/Module.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringSwitch.h" +using namespace clang; + +Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, + bool IsFramework, bool IsExplicit) + : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), + Umbrella(), IsAvailable(true), IsFromModuleFile(false), + IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), + InferSubmodules(false), InferExplicitSubmodules(false), + InferExportWildcard(false), NameVisibility(Hidden) +{ + if (Parent) { + if (!Parent->isAvailable()) + IsAvailable = false; + if (Parent->IsSystem) + IsSystem = true; + + Parent->SubModuleIndex[Name] = Parent->SubModules.size(); + Parent->SubModules.push_back(this); + } +} + +Module::~Module() { + for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); + I != IEnd; ++I) { + delete *I; + } + +} + +/// \brief Determine whether a translation unit built using the current +/// language options has the given feature. +static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, + const TargetInfo &Target) { + return llvm::StringSwitch<bool>(Feature) + .Case("altivec", LangOpts.AltiVec) + .Case("blocks", LangOpts.Blocks) + .Case("cplusplus", LangOpts.CPlusPlus) + .Case("cplusplus11", LangOpts.CPlusPlus0x) + .Case("objc", LangOpts.ObjC1) + .Case("objc_arc", LangOpts.ObjCAutoRefCount) + .Case("opencl", LangOpts.OpenCL) + .Case("tls", Target.isTLSSupported()) + .Default(Target.hasFeature(Feature)); +} + +bool +Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, + StringRef &Feature) const { + if (IsAvailable) + return true; + + for (const Module *Current = this; Current; Current = Current->Parent) { + for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) { + if (!hasFeature(Current->Requires[I], LangOpts, Target)) { + Feature = Current->Requires[I]; + return false; + } + } + } + + llvm_unreachable("could not find a reason why module is unavailable"); +} + +bool Module::isSubModuleOf(Module *Other) const { + const Module *This = this; + do { + if (This == Other) + return true; + + This = This->Parent; + } while (This); + + return false; +} + +const Module *Module::getTopLevelModule() const { + const Module *Result = this; + while (Result->Parent) + Result = Result->Parent; + + return Result; +} + +std::string Module::getFullModuleName() const { + llvm::SmallVector<StringRef, 2> Names; + + // Build up the set of module names (from innermost to outermost). + for (const Module *M = this; M; M = M->Parent) + Names.push_back(M->Name); + + std::string Result; + for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), + IEnd = Names.rend(); + I != IEnd; ++I) { + if (!Result.empty()) + Result += '.'; + + Result += *I; + } + + return Result; +} + +const DirectoryEntry *Module::getUmbrellaDir() const { + if (const FileEntry *Header = getUmbrellaHeader()) + return Header->getDir(); + + return Umbrella.dyn_cast<const DirectoryEntry *>(); +} + +void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, + const TargetInfo &Target) { + Requires.push_back(Feature); + + // If this feature is currently available, we're done. + if (hasFeature(Feature, LangOpts, Target)) + return; + + if (!IsAvailable) + return; + + llvm::SmallVector<Module *, 2> Stack; + Stack.push_back(this); + while (!Stack.empty()) { + Module *Current = Stack.back(); + Stack.pop_back(); + + if (!Current->IsAvailable) + continue; + + Current->IsAvailable = false; + for (submodule_iterator Sub = Current->submodule_begin(), + SubEnd = Current->submodule_end(); + Sub != SubEnd; ++Sub) { + if ((*Sub)->IsAvailable) + Stack.push_back(*Sub); + } + } +} + +Module *Module::findSubmodule(StringRef Name) const { + llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); + if (Pos == SubModuleIndex.end()) + return 0; + + return SubModules[Pos->getValue()]; +} + +static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) { + for (unsigned I = 0, N = Id.size(); I != N; ++I) { + if (I) + OS << "."; + OS << Id[I].first; + } +} + +void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { + OS.indent(Indent); + if (IsFramework) + OS << "framework "; + if (IsExplicit) + OS << "explicit "; + OS << "module " << Name; + + if (IsSystem) { + OS.indent(Indent + 2); + OS << " [system]"; + } + + OS << " {\n"; + + if (!Requires.empty()) { + OS.indent(Indent + 2); + OS << "requires "; + for (unsigned I = 0, N = Requires.size(); I != N; ++I) { + if (I) + OS << ", "; + OS << Requires[I]; + } + OS << "\n"; + } + + if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { + OS.indent(Indent + 2); + OS << "umbrella header \""; + OS.write_escaped(UmbrellaHeader->getName()); + OS << "\"\n"; + } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { + OS.indent(Indent + 2); + OS << "umbrella \""; + OS.write_escaped(UmbrellaDir->getName()); + OS << "\"\n"; + } + + for (unsigned I = 0, N = Headers.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "header \""; + OS.write_escaped(Headers[I]->getName()); + OS << "\"\n"; + } + + for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); + MI != MIEnd; ++MI) + (*MI)->print(OS, Indent + 2); + + for (unsigned I = 0, N = Exports.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "export "; + if (Module *Restriction = Exports[I].getPointer()) { + OS << Restriction->getFullModuleName(); + if (Exports[I].getInt()) + OS << ".*"; + } else { + OS << "*"; + } + OS << "\n"; + } + + for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "export "; + printModuleId(OS, UnresolvedExports[I].Id); + if (UnresolvedExports[I].Wildcard) { + if (UnresolvedExports[I].Id.empty()) + OS << "*"; + else + OS << ".*"; + } + OS << "\n"; + } + + if (InferSubmodules) { + OS.indent(Indent + 2); + if (InferExplicitSubmodules) + OS << "explicit "; + OS << "module * {\n"; + if (InferExportWildcard) { + OS.indent(Indent + 4); + OS << "export *\n"; + } + OS.indent(Indent + 2); + OS << "}\n"; + } + + OS.indent(Indent); + OS << "}\n"; +} + +void Module::dump() const { + print(llvm::errs()); +} + + diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp index 6e4f3e6..bb5a10a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp @@ -115,6 +115,10 @@ bool FullSourceLoc::isBeforeInTranslationUnitThan(SourceLocation Loc) const { return SrcMgr->isBeforeInTranslationUnit(*this, Loc); } +void FullSourceLoc::dump() const { + SourceLocation::dump(*SrcMgr); +} + const char *FullSourceLoc::getCharacterData(bool *Invalid) const { assert(isValid()); return SrcMgr->getCharacterData(*this, Invalid); diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp index 364663e..cef091c 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp @@ -71,7 +71,11 @@ unsigned ContentCache::getSize() const { void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree) { - assert(B != Buffer.getPointer()); + if (B == Buffer.getPointer()) { + assert(0 && "Replacing with the same buffer"); + Buffer.setInt(DoNotFree? DoNotFreeFlag : 0); + return; + } if (shouldFreeBuffer()) delete Buffer.getPointer(); @@ -366,7 +370,8 @@ LineTableInfo &SourceManager::getLineTable() { SourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr) : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true), ExternalSLocEntries(0), LineTable(0), NumLinearScans(0), - NumBinaryProbes(0), FakeBufferForRecovery(0) { + NumBinaryProbes(0), FakeBufferForRecovery(0), + FakeContentCacheForRecovery(0) { clearIDTables(); Diag.setSourceManager(this); } @@ -378,16 +383,21 @@ SourceManager::~SourceManager() { // content cache objects are bump pointer allocated, we just have to run the // dtors, but we call the deallocate method for completeness. for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) { - MemBufferInfos[i]->~ContentCache(); - ContentCacheAlloc.Deallocate(MemBufferInfos[i]); + if (MemBufferInfos[i]) { + MemBufferInfos[i]->~ContentCache(); + ContentCacheAlloc.Deallocate(MemBufferInfos[i]); + } } for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) { - I->second->~ContentCache(); - ContentCacheAlloc.Deallocate(I->second); + if (I->second) { + I->second->~ContentCache(); + ContentCacheAlloc.Deallocate(I->second); + } } delete FakeBufferForRecovery; + delete FakeContentCacheForRecovery; for (llvm::DenseMap<FileID, MacroArgsMap *>::iterator I = MacroArgsCacheMap.begin(),E = MacroArgsCacheMap.end(); I!=E; ++I) { @@ -461,6 +471,25 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { return Entry; } +const SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index, + bool *Invalid) const { + assert(!SLocEntryLoaded[Index]); + if (ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2))) { + if (Invalid) + *Invalid = true; + // If the file of the SLocEntry changed we could still have loaded it. + if (!SLocEntryLoaded[Index]) { + // Try to recover; create a SLocEntry so the rest of clang can handle it. + LoadedSLocEntryTable[Index] = SLocEntry::get(0, + FileInfo::get(SourceLocation(), + getFakeContentCacheForRecovery(), + SrcMgr::C_User)); + } + } + + return LoadedSLocEntryTable[Index]; +} + std::pair<int, unsigned> SourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize) { @@ -483,6 +512,18 @@ const llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const { return FakeBufferForRecovery; } +/// \brief As part of recovering from missing or changed content, produce a +/// fake content cache. +const SrcMgr::ContentCache * +SourceManager::getFakeContentCacheForRecovery() const { + if (!FakeContentCacheForRecovery) { + FakeContentCacheForRecovery = new ContentCache(); + FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(), + /*DoNotFree=*/true); + } + return FakeContentCacheForRecovery; +} + //===----------------------------------------------------------------------===// // Methods to create new FileID's and macro expansions. //===----------------------------------------------------------------------===// @@ -580,6 +621,7 @@ void SourceManager::overrideFileContents(const FileEntry *SourceFile, assert(IR && "getOrCreateContentCache() cannot return NULL"); const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(Buffer, DoNotFree); + const_cast<SrcMgr::ContentCache *>(IR)->BufferOverridden = true; } void SourceManager::overrideFileContents(const FileEntry *SourceFile, @@ -730,11 +772,11 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { /// This function knows that the SourceLocation is in a loaded buffer, not a /// local one. FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { - assert(SLocOffset >= CurrentLoadedOffset && "Bad function choice"); - // Sanity checking, otherwise a bug may lead to hanging in release build. - if (SLocOffset < CurrentLoadedOffset) + if (SLocOffset < CurrentLoadedOffset) { + assert(0 && "Invalid SLocOffset or bad function choice"); return FileID(); + } // Essentially the same as the local case, but the loaded array is sorted // in the other direction. @@ -946,13 +988,20 @@ const char *SourceManager::getCharacterData(SourceLocation SL, unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid) const { bool MyInvalid = false; - const char *Buf = getBuffer(FID, &MyInvalid)->getBufferStart(); + const llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid); if (Invalid) *Invalid = MyInvalid; if (MyInvalid) return 1; + if (FilePos >= MemBuf->getBufferSize()) { + if (Invalid) + *Invalid = MyInvalid; + return 1; + } + + const char *Buf = MemBuf->getBufferStart(); unsigned LineStart = FilePos; while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r') --LineStart; @@ -988,6 +1037,10 @@ unsigned SourceManager::getPresumedColumnNumber(SourceLocation Loc, return getPresumedLoc(Loc).getColumn(); } +#ifdef __SSE2__ +#include <emmintrin.h> +#endif + static LLVM_ATTRIBUTE_NOINLINE void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI, llvm::BumpPtrAllocator &Alloc, @@ -1013,11 +1066,44 @@ static void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI, unsigned Offs = 0; while (1) { // Skip over the contents of the line. - // TODO: Vectorize this? This is very performance sensitive for programs - // with lots of diagnostics and in -E mode. const unsigned char *NextBuf = (const unsigned char *)Buf; + +#ifdef __SSE2__ + // Try to skip to the next newline using SSE instructions. This is very + // performance sensitive for programs with lots of diagnostics and in -E + // mode. + __m128i CRs = _mm_set1_epi8('\r'); + __m128i LFs = _mm_set1_epi8('\n'); + + // First fix up the alignment to 16 bytes. + while (((uintptr_t)NextBuf & 0xF) != 0) { + if (*NextBuf == '\n' || *NextBuf == '\r' || *NextBuf == '\0') + goto FoundSpecialChar; + ++NextBuf; + } + + // Scan 16 byte chunks for '\r' and '\n'. Ignore '\0'. + while (NextBuf+16 <= End) { + __m128i Chunk = *(__m128i*)NextBuf; + __m128i Cmp = _mm_or_si128(_mm_cmpeq_epi8(Chunk, CRs), + _mm_cmpeq_epi8(Chunk, LFs)); + unsigned Mask = _mm_movemask_epi8(Cmp); + + // If we found a newline, adjust the pointer and jump to the handling code. + if (Mask != 0) { + NextBuf += llvm::CountTrailingZeros_32(Mask); + goto FoundSpecialChar; + } + NextBuf += 16; + } +#endif + while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0') ++NextBuf; + +#ifdef __SSE2__ +FoundSpecialChar: +#endif Offs += NextBuf-Buf; Buf = NextBuf; @@ -1508,9 +1594,10 @@ SourceLocation SourceManager::translateLineCol(FileID FID, return FileLoc.getLocWithOffset(Size); } + const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this); unsigned FilePos = Content->SourceLineCache[Line - 1]; - const char *Buf = Content->getBuffer(Diag, *this)->getBufferStart() + FilePos; - unsigned BufLength = Content->getBuffer(Diag, *this)->getBufferEnd() - Buf; + const char *Buf = Buffer->getBufferStart() + FilePos; + unsigned BufLength = Buffer->getBufferSize() - FilePos; if (BufLength == 0) return FileLoc.getLocWithOffset(FilePos); @@ -1568,14 +1655,31 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr, continue; } - if (!Entry.getExpansion().isMacroArgExpansion()) + const ExpansionInfo &ExpInfo = Entry.getExpansion(); + + if (ExpInfo.getExpansionLocStart().isFileID()) { + if (!isInFileID(ExpInfo.getExpansionLocStart(), FID)) + return; // No more files/macros that may be "contained" in this file. + } + + if (!ExpInfo.isMacroArgExpansion()) + continue; + + SourceLocation SpellLoc = ExpInfo.getSpellingLoc(); + while (!SpellLoc.isFileID()) { + std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(SpellLoc); + const ExpansionInfo &Info = getSLocEntry(LocInfo.first).getExpansion(); + if (!Info.isMacroArgExpansion()) + break; + SpellLoc = Info.getSpellingLoc().getLocWithOffset(LocInfo.second); + } + if (!SpellLoc.isFileID()) continue; - - SourceLocation SpellLoc = - getSpellingLoc(Entry.getExpansion().getSpellingLoc()); + unsigned BeginOffs; if (!isInFileID(SpellLoc, FID, &BeginOffs)) - return; // No more files/macros that may be "contained" in this file. + continue; + unsigned EndOffs = BeginOffs + getFileIDSize(FileID::get(ID)); // Add a new chunk for this macro argument. A previous macro argument chunk @@ -1648,7 +1752,7 @@ static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc, SourceLocation UpperLoc; const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(Loc.first); if (Entry.isExpansion()) - UpperLoc = Entry.getExpansion().getExpansionLocEnd(); + UpperLoc = Entry.getExpansion().getExpansionLocStart(); else UpperLoc = Entry.getFile().getIncludeLoc(); diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp index 593db2b..f938b5a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp @@ -27,6 +27,7 @@ static const LangAS::Map DefaultAddrSpaceMap = { 0 }; TargetInfo::TargetInfo(const std::string &T) : Triple(T) { // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or // SPARC. These should be overridden by concrete targets as needed. + BigEndian = true; TLSSupported = true; NoAsmVariants = false; PointerWidth = PointerAlign = 32; @@ -34,6 +35,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) { IntWidth = IntAlign = 32; LongWidth = LongAlign = 32; LongLongWidth = LongLongAlign = 64; + SuitableAlign = 64; HalfWidth = 16; HalfAlign = 16; FloatWidth = 32; @@ -74,6 +76,9 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) { // Default to no types using fpret. RealTypeUsesObjCFPRet = 0; + // Default to not using fp2ret for __Complex long double + ComplexLongDoubleUsesFP2Ret = false; + // Default to using the Itanium ABI. CXXABI = CXXABI_Itanium; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index ae5f270..1ad37c4 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -54,6 +54,14 @@ static void DefineStd(MacroBuilder &Builder, StringRef MacroName, Builder.defineMacro("__" + MacroName + "__"); } +static void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, + bool Tuning = true) { + Builder.defineMacro("__" + CPUName); + Builder.defineMacro("__" + CPUName + "__"); + if (Tuning) + Builder.defineMacro("__tune_" + CPUName + "__"); +} + //===----------------------------------------------------------------------===// // Defines specific to certain operating systems. //===----------------------------------------------------------------------===// @@ -99,13 +107,6 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, // allow this in C, since one might have block pointers in structs that // are used in pure C code and in Objective-C ARC. Builder.defineMacro("__unsafe_unretained", ""); - - // The Objective-C bridged cast keywords are defined to nothing in non-ARC - // mode; then they become normal, C-style casts. - Builder.defineMacro("__bridge", ""); - Builder.defineMacro("__bridge_transfer", ""); - Builder.defineMacro("__bridge_retained", ""); - Builder.defineMacro("__bridge_retain", ""); } if (Opts.Static) @@ -118,36 +119,15 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, // Get the platform type and version number from the triple. unsigned Maj, Min, Rev; - - // If no version was given, default to to 10.4.0, for simplifying tests. - if (Triple.getOSName() == "darwin" || Triple.getOSName() == "osx") { + if (Triple.isMacOSX()) { + Triple.getMacOSXVersion(Maj, Min, Rev); PlatformName = "macosx"; - Min = Rev = 0; - Maj = 8; } else { - // Otherwise, honor all three triple forms ("-darwinNNN[-iphoneos]", - // "-osxNNN", and "-iosNNN"). - - if (Triple.getOS() == llvm::Triple::Darwin) { - // For historical reasons that make little sense, the version passed here - // is the "darwin" version, which drops the 10 and offsets by 4. - Triple.getOSVersion(Maj, Min, Rev); - - if (Triple.getEnvironmentName() == "iphoneos") { - PlatformName = "ios"; - } else { - PlatformName = "macosx"; - Rev = Min; - Min = Maj - 4; - Maj = 10; - } - } else { - Triple.getOSVersion(Maj, Min, Rev); - PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); - } + Triple.getOSVersion(Maj, Min, Rev); + PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); } - // If -ccc-host-triple arch-pc-win32-macho option specified, we're + // If -target arch-pc-win32-macho option specified, we're // generating code for Win32 ABI. No need to emit // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__. if (PlatformName == "win32") { @@ -156,7 +136,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, } // Set the appropriate OS version define. - if (PlatformName == "ios") { + if (Triple.getOS() == llvm::Triple::IOS) { assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); char Str[6]; Str[0] = '0' + Maj; @@ -217,6 +197,12 @@ public: return "__TEXT,__StaticInit,regular,pure_instructions"; } + /// Darwin does not support protected visibility. Darwin's "default" + /// is very similar to ELF's "protected"; Darwin requires a "weak" + /// attribute on declarations that can be dynamically replaced. + virtual bool hasProtectedVisibility() const { + return false; + } }; @@ -236,7 +222,18 @@ protected: } public: DragonFlyBSDTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) {} + : OSTargetInfo<Target>(triple) { + this->UserLabelPrefix = ""; + + llvm::Triple Triple(triple); + switch (Triple.getArch()) { + default: + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->MCountName = ".mcount"; + break; + } + } }; // FreeBSD Target @@ -249,7 +246,7 @@ protected: unsigned Release = Triple.getOSMajorVersion(); if (Release == 0U) - Release = 8U; + Release = 8; Builder.defineMacro("__FreeBSD__", Twine(Release)); Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U)); @@ -298,6 +295,7 @@ protected: Builder.defineMacro("_EM_LSIZE", "4"); Builder.defineMacro("_EM_FSIZE", "4"); Builder.defineMacro("_EM_DSIZE", "8"); + Builder.defineMacro("__ELF__"); DefineStd(Builder, "unix", Opts); } public: @@ -329,6 +327,10 @@ public: this->UserLabelPrefix = ""; this->WIntType = TargetInfo::UnsignedInt; } + + virtual const char *getStaticInitSectionSpecifier() const { + return ".text.startup"; + } }; // NetBSD Target @@ -367,7 +369,26 @@ protected: } public: OpenBSDTargetInfo(const std::string &triple) - : OSTargetInfo<Target>(triple) {} + : OSTargetInfo<Target>(triple) { + this->UserLabelPrefix = ""; + + llvm::Triple Triple(triple); + switch (Triple.getArch()) { + default: + case llvm::Triple::x86: + case llvm::Triple::x86_64: + case llvm::Triple::arm: + case llvm::Triple::sparc: + this->MCountName = "__mcount"; + break; + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + case llvm::Triple::ppc: + case llvm::Triple::sparcv9: + this->MCountName = "_mcount"; + break; + } + } }; // PSP Target @@ -408,13 +429,14 @@ public: PS3PPUTargetInfo(const std::string& triple) : OSTargetInfo<Target>(triple) { this->UserLabelPrefix = ""; - this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32; + this->LongWidth = this->LongAlign = 32; + this->PointerWidth = this->PointerAlign = 32; this->IntMaxType = TargetInfo::SignedLongLong; this->UIntMaxType = TargetInfo::UnsignedLongLong; this->Int64Type = TargetInfo::SignedLongLong; this->SizeType = TargetInfo::UnsignedInt; this->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-v128:128:128-n32"; + "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32"; } }; @@ -468,12 +490,26 @@ protected: Builder.defineMacro("__ELF__"); Builder.defineMacro("__svr4__"); Builder.defineMacro("__SVR4"); + // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and + // newer, but to 500 for everything else. feature_test.h has a check to + // ensure that you are not using C99 with an old version of X/Open or C89 + // with a new version. + if (Opts.C99 || Opts.C11) + Builder.defineMacro("_XOPEN_SOURCE", "600"); + else + Builder.defineMacro("_XOPEN_SOURCE", "500"); + if (Opts.CPlusPlus) + Builder.defineMacro("__C99FEATURES__"); + Builder.defineMacro("_LARGEFILE_SOURCE"); + Builder.defineMacro("_LARGEFILE64_SOURCE"); + Builder.defineMacro("__EXTENSIONS__"); + Builder.defineMacro("_REENTRANT"); } public: SolarisTargetInfo(const std::string& triple) : OSTargetInfo<Target>(triple) { this->UserLabelPrefix = ""; - this->WCharType = this->SignedLong; + this->WCharType = this->SignedInt; // FIXME: WIntType should be SignedLong } }; @@ -538,7 +574,10 @@ class PPCTargetInfo : public TargetInfo { static const char * const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; public: - PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {} + PPCTargetInfo(const std::string& triple) : TargetInfo(triple) { + LongDoubleWidth = LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; + } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { @@ -546,9 +585,13 @@ public: NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin; } + virtual bool isCLZForZeroUndef() const { return false; } + virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const; + virtual bool hasFeature(StringRef Feature) const; + virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -701,7 +744,11 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, } } +bool PPCTargetInfo::hasFeature(StringRef Feature) const { + return Feature == "powerpc"; +} + const char * const PPCTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -814,13 +861,21 @@ public: "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32"; switch (getTriple().getOS()) { + case llvm::Triple::Linux: case llvm::Triple::FreeBSD: case llvm::Triple::NetBSD: SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; break; default: break; } + + if (getTriple().getOS() == llvm::Triple::FreeBSD) { + LongDoubleWidth = LongDoubleAlign = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble; + } } virtual const char *getVAListDeclaration() const { @@ -846,6 +901,11 @@ public: Int64Type = SignedLong; 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-v128:128:128-n32:64"; + + if (getTriple().getOS() == llvm::Triple::FreeBSD) { + LongDoubleWidth = LongDoubleAlign = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble; + } } virtual const char *getVAListDeclaration() const { return "typedef char* __builtin_va_list;"; @@ -862,6 +922,10 @@ public: : DarwinTargetInfo<PPC32TargetInfo>(triple) { HasAlignMac68kSupport = true; BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool? + LongLongAlign = 32; + SuitableAlign = 128; + 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;"; @@ -874,6 +938,7 @@ public: DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo<PPC64TargetInfo>(triple) { HasAlignMac68kSupport = true; + SuitableAlign = 128; } }; } // end anonymous namespace. @@ -890,6 +955,7 @@ namespace { std::vector<llvm::StringRef> AvailableFeatures; public: PTXTargetInfo(const std::string& triple) : TargetInfo(triple) { + BigEndian = false; TLSSupported = false; LongWidth = LongAlign = 64; AddrSpaceMap = &PTXAddrSpaceMap; @@ -924,7 +990,10 @@ namespace { Records = BuiltinInfo; NumRecords = clang::PTX::LastTSBuiltin-Builtin::FirstTSBuiltin; } - + virtual bool hasFeature(StringRef Feature) const { + return Feature == "ptx"; + } + virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -948,7 +1017,7 @@ namespace { } virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const; }; @@ -970,7 +1039,7 @@ namespace { } bool PTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const { if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(), Name)) { @@ -1023,6 +1092,10 @@ public: virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const; + virtual bool hasFeature(StringRef Feature) const { + return Feature == "mblaze"; + } + virtual const char *getVAListDeclaration() const { return "typedef char* __builtin_va_list;"; } @@ -1146,6 +1219,8 @@ static const char* const GCCRegNames[] = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", + "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", + "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", }; const TargetInfo::AddlRegName AddlRegNames[] = { @@ -1163,14 +1238,18 @@ const TargetInfo::AddlRegName AddlRegNames[] = { // most of the implementation can be shared. class X86TargetInfo : public TargetInfo { enum X86SSEEnum { - NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42 + NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2 } SSELevel; enum MMX3DNowEnum { NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon } MMX3DNowLevel; bool HasAES; - bool HasAVX; + bool HasLZCNT; + bool HasBMI; + bool HasBMI2; + bool HasPOPCNT; + bool HasFMA4; /// \brief Enumeration of all of the X86 CPUs supported by Clang. /// @@ -1252,6 +1331,7 @@ class X86TargetInfo : public TargetInfo { CK_Corei7, CK_Corei7AVX, CK_CoreAVXi, + CK_CoreAVX2, //@} /// \name K6 @@ -1283,6 +1363,20 @@ class X86TargetInfo : public TargetInfo { CK_Opteron, CK_OpteronSSE3, CK_AMDFAM10, + //@} + + /// \name Bobcat + /// Bobcat architecture processors. + //@{ + CK_BTVER1, + //@} + + /// \name Bulldozer + /// Bulldozer architecture processors. + //@{ + CK_BDVER1, + CK_BDVER2, + //@} /// This specification is deprecated and will be removed in the future. /// Users should prefer \see CK_K8. @@ -1300,9 +1394,15 @@ class X86TargetInfo : public TargetInfo { public: X86TargetInfo(const std::string& triple) : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow), - HasAES(false), HasAVX(false), CPU(CK_Generic) { + HasAES(false), HasLZCNT(false), HasBMI(false), HasBMI2(false), + HasPOPCNT(false), HasFMA4(false), CPU(CK_Generic) { + BigEndian = false; LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } + virtual unsigned getFloatEvalMethod() const { + // X87 evaluates with 80 bits "long double" precision. + return SSELevel == NoSSE ? 2 : 0; + } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { Records = BuiltinInfo; @@ -1332,12 +1432,17 @@ public: virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const; virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const; virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const; + virtual bool hasFeature(StringRef Feature) const; virtual void HandleTargetFeatures(std::vector<std::string> &Features); virtual const char* getABI() const { - return MMX3DNowLevel == NoMMX3DNow ? "no-mmx" : ""; + if (PointerWidth == 64 && SSELevel >= AVX) + return "avx"; + else if (PointerWidth == 32 && MMX3DNowLevel == NoMMX3DNow) + return "no-mmx"; + return ""; } virtual bool setCPU(const std::string &Name) { CPU = llvm::StringSwitch<CPUKind>(Name) @@ -1367,6 +1472,7 @@ public: .Case("corei7", CK_Corei7) .Case("corei7-avx", CK_Corei7AVX) .Case("core-avx-i", CK_CoreAVXi) + .Case("core-avx2", CK_CoreAVX2) .Case("k6", CK_K6) .Case("k6-2", CK_K6_2) .Case("k6-3", CK_K6_3) @@ -1383,6 +1489,9 @@ public: .Case("opteron", CK_Opteron) .Case("opteron-sse3", CK_OpteronSSE3) .Case("amdfam10", CK_AMDFAM10) + .Case("btver1", CK_BTVER1) + .Case("bdver1", CK_BDVER1) + .Case("bdver2", CK_BDVER2) .Case("x86-64", CK_x86_64) .Case("geode", CK_Geode) .Default(CK_Generic); @@ -1436,6 +1545,7 @@ public: case CK_Corei7: case CK_Corei7AVX: case CK_CoreAVXi: + case CK_CoreAVX2: case CK_Athlon64: case CK_Athlon64SSE3: case CK_AthlonFX: @@ -1444,6 +1554,9 @@ public: case CK_Opteron: case CK_OpteronSSE3: case CK_AMDFAM10: + case CK_BTVER1: + case CK_BDVER1: + case CK_BDVER2: case CK_x86_64: return true; } @@ -1465,6 +1578,12 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { Features["sse4a"] = false; Features["aes"] = false; Features["avx"] = false; + Features["avx2"] = false; + Features["lzcnt"] = false; + Features["bmi"] = false; + Features["bmi2"] = false; + Features["popcnt"] = false; + Features["fma4"] = false; // FIXME: This *really* should not be here. @@ -1509,8 +1628,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { break; case CK_Penryn: setFeatureEnabled(Features, "mmx", true); - setFeatureEnabled(Features, "sse4", true); - Features["sse42"] = false; + setFeatureEnabled(Features, "sse4.1", true); break; case CK_Atom: setFeatureEnabled(Features, "mmx", true); @@ -1528,6 +1646,15 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { setFeatureEnabled(Features, "aes", true); //setFeatureEnabled(Features, "avx", true); break; + case CK_CoreAVX2: + setFeatureEnabled(Features, "mmx", true); + setFeatureEnabled(Features, "sse4", true); + setFeatureEnabled(Features, "aes", true); + setFeatureEnabled(Features, "lzcnt", true); + setFeatureEnabled(Features, "bmi", true); + setFeatureEnabled(Features, "bmi2", true); + //setFeatureEnabled(Features, "avx2", true); + break; case CK_K6: case CK_WinChipC6: setFeatureEnabled(Features, "mmx", true); @@ -1567,6 +1694,15 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { setFeatureEnabled(Features, "sse4a", true); setFeatureEnabled(Features, "3dnowa", true); break; + case CK_BTVER1: + setFeatureEnabled(Features, "ssse3", true); + setFeatureEnabled(Features, "sse4a", true); + case CK_BDVER1: + case CK_BDVER2: + setFeatureEnabled(Features, "sse4", true); + setFeatureEnabled(Features, "sse4a", true); + setFeatureEnabled(Features, "aes", true); + break; case CK_C3_2: setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse", true); @@ -1575,7 +1711,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { } bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const { // FIXME: This *really* should not be here. We need some way of translating // options into llvm subtarget features. @@ -1600,7 +1736,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, Features["ssse3"] = true; else if (Name == "sse4" || Name == "sse4.2") Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["ssse3"] = Features["sse41"] = Features["sse42"] = true; + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["popcnt"] = true; else if (Name == "sse4.1") Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = true; @@ -1613,21 +1750,39 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, else if (Name == "avx") Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = - Features["avx"] = true; + Features["popcnt"] = Features["avx"] = true; + else if (Name == "avx2") + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["popcnt"] = Features["avx"] = Features["avx2"] = 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; else if (Name == "sse4a") - Features["mmx"] = Features["sse4a"] = true; + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["lzcnt"] = Features["popcnt"] = Features["sse4a"] = true; + else if (Name == "lzcnt") + Features["lzcnt"] = true; + else if (Name == "bmi") + Features["bmi"] = true; + else if (Name == "bmi2") + Features["bmi2"] = true; + else if (Name == "popcnt") + Features["popcnt"] = true; } else { if (Name == "mmx") Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false; else if (Name == "sse") Features["sse"] = Features["sse2"] = Features["sse3"] = - Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; + Features["ssse3"] = Features["sse41"] = Features["sse42"] = + Features["sse4a"] = false; else if (Name == "sse2") Features["sse2"] = Features["sse3"] = Features["ssse3"] = - Features["sse41"] = Features["sse42"] = false; + Features["sse41"] = Features["sse42"] = Features["sse4a"] = false; else if (Name == "sse3") Features["sse3"] = Features["ssse3"] = Features["sse41"] = - Features["sse42"] = false; + Features["sse42"] = Features["sse4a"] = false; else if (Name == "ssse3") Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; else if (Name == "sse4" || Name == "sse4.1") @@ -1641,9 +1796,21 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, else if (Name == "aes") Features["aes"] = false; else if (Name == "avx") - Features["avx"] = false; + Features["avx"] = Features["avx2"] = Features["fma4"] = false; + else if (Name == "avx2") + Features["avx2"] = false; else if (Name == "sse4a") Features["sse4a"] = false; + else if (Name == "lzcnt") + Features["lzcnt"] = false; + else if (Name == "bmi") + Features["bmi"] = false; + else if (Name == "bmi2") + Features["bmi2"] = false; + else if (Name == "popcnt") + Features["popcnt"] = false; + else if (Name == "fma4") + Features["fma4"] = false; } return true; @@ -1658,20 +1825,42 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { if (Features[i][0] == '-') continue; - if (Features[i].substr(1) == "aes") { + StringRef Feature = StringRef(Features[i]).substr(1); + + if (Feature == "aes") { HasAES = true; continue; } - // FIXME: Not sure yet how to treat AVX in regard to SSE levels. - // For now let it be enabled together with other SSE levels. - if (Features[i].substr(1) == "avx") { - HasAVX = true; + if (Feature == "lzcnt") { + HasLZCNT = true; + continue; + } + + if (Feature == "bmi") { + HasBMI = true; + continue; + } + + if (Feature == "bmi2") { + HasBMI2 = true; + continue; + } + + if (Feature == "popcnt") { + HasPOPCNT = true; + continue; + } + + if (Feature == "fma4") { + HasFMA4 = true; continue; } assert(Features[i][0] == '+' && "Invalid target feature!"); - X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1)) + X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) + .Case("avx2", AVX2) + .Case("avx", AVX) .Case("sse42", SSE42) .Case("sse41", SSE41) .Case("ssse3", SSSE3) @@ -1682,7 +1871,7 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { SSELevel = std::max(SSELevel, Level); MMX3DNowEnum ThreeDNowLevel = - llvm::StringSwitch<MMX3DNowEnum>(Features[i].substr(1)) + llvm::StringSwitch<MMX3DNowEnum>(Feature) .Case("3dnowa", AMD3DNowAthlon) .Case("3dnow", AMD3DNow) .Case("mmx", MMX) @@ -1705,8 +1894,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { // Target identification. if (PointerWidth == 64) { - Builder.defineMacro("_LP64"); - Builder.defineMacro("__LP64__"); + if (getLongWidth() == 64) { + Builder.defineMacro("_LP64"); + Builder.defineMacro("__LP64__"); + } Builder.defineMacro("__amd64__"); Builder.defineMacro("__amd64"); Builder.defineMacro("__x86_64"); @@ -1729,9 +1920,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_WinChipC6: case CK_WinChip2: case CK_C3: - Builder.defineMacro("__i486"); - Builder.defineMacro("__i486__"); - Builder.defineMacro("__tune_i486__"); + defineCPUMacros(Builder, "i486"); break; case CK_PentiumMMX: Builder.defineMacro("__pentium_mmx__"); @@ -1739,12 +1928,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, // Fallthrough case CK_i586: case CK_Pentium: - Builder.defineMacro("__i586"); - Builder.defineMacro("__i586__"); - Builder.defineMacro("__tune_i586__"); - Builder.defineMacro("__pentium"); - Builder.defineMacro("__pentium__"); - Builder.defineMacro("__tune_pentium__"); + defineCPUMacros(Builder, "i586"); + defineCPUMacros(Builder, "pentium"); break; case CK_Pentium3: case CK_Pentium3M: @@ -1768,34 +1953,25 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, break; case CK_Pentium4: case CK_Pentium4M: - Builder.defineMacro("__pentium4"); - Builder.defineMacro("__pentium4__"); - Builder.defineMacro("__tune_pentium4__"); + defineCPUMacros(Builder, "pentium4"); break; case CK_Yonah: case CK_Prescott: case CK_Nocona: - Builder.defineMacro("__nocona"); - Builder.defineMacro("__nocona__"); - Builder.defineMacro("__tune_nocona__"); + defineCPUMacros(Builder, "nocona"); break; case CK_Core2: case CK_Penryn: - Builder.defineMacro("__core2"); - Builder.defineMacro("__core2__"); - Builder.defineMacro("__tune_core2__"); + defineCPUMacros(Builder, "core2"); break; case CK_Atom: - Builder.defineMacro("__atom"); - Builder.defineMacro("__atom__"); - Builder.defineMacro("__tune_atom__"); + defineCPUMacros(Builder, "atom"); break; case CK_Corei7: case CK_Corei7AVX: case CK_CoreAVXi: - Builder.defineMacro("__corei7"); - Builder.defineMacro("__corei7__"); - Builder.defineMacro("__tune_corei7__"); + case CK_CoreAVX2: + defineCPUMacros(Builder, "corei7"); break; case CK_K6_2: Builder.defineMacro("__k6_2__"); @@ -1811,18 +1987,14 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, } // Fallthrough case CK_K6: - Builder.defineMacro("__k6"); - Builder.defineMacro("__k6__"); - Builder.defineMacro("__tune_k6__"); + defineCPUMacros(Builder, "k6"); break; case CK_Athlon: case CK_AthlonThunderbird: case CK_Athlon4: case CK_AthlonXP: case CK_AthlonMP: - Builder.defineMacro("__athlon"); - Builder.defineMacro("__athlon__"); - Builder.defineMacro("__tune_athlon__"); + defineCPUMacros(Builder, "athlon"); if (SSELevel != NoSSE) { Builder.defineMacro("__athlon_sse__"); Builder.defineMacro("__tune_athlon_sse__"); @@ -1836,19 +2008,22 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Athlon64: case CK_Athlon64SSE3: case CK_AthlonFX: - Builder.defineMacro("__k8"); - Builder.defineMacro("__k8__"); - Builder.defineMacro("__tune_k8__"); + defineCPUMacros(Builder, "k8"); break; case CK_AMDFAM10: - Builder.defineMacro("__amdfam10"); - Builder.defineMacro("__amdfam10__"); - Builder.defineMacro("__tune_amdfam10__"); + defineCPUMacros(Builder, "amdfam10"); + break; + case CK_BTVER1: + defineCPUMacros(Builder, "btver1"); + break; + case CK_BDVER1: + defineCPUMacros(Builder, "bdver1"); + break; + case CK_BDVER2: + defineCPUMacros(Builder, "bdver2"); break; case CK_Geode: - Builder.defineMacro("__geode"); - Builder.defineMacro("__geode__"); - Builder.defineMacro("__tune_geode__"); + defineCPUMacros(Builder, "geode"); break; } @@ -1864,11 +2039,27 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasAES) Builder.defineMacro("__AES__"); - if (HasAVX) - Builder.defineMacro("__AVX__"); + if (HasLZCNT) + Builder.defineMacro("__LZCNT__"); + + if (HasBMI) + Builder.defineMacro("__BMI__"); + + if (HasBMI2) + Builder.defineMacro("__BMI2__"); + + if (HasPOPCNT) + Builder.defineMacro("__POPCNT__"); + + if (HasFMA4) + Builder.defineMacro("__FMA4__"); // Each case falls through to the previous one here. switch (SSELevel) { + case AVX2: + Builder.defineMacro("__AVX2__"); + case AVX: + Builder.defineMacro("__AVX__"); case SSE42: Builder.defineMacro("__SSE4_2__"); case SSE41: @@ -1889,6 +2080,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (Opts.MicrosoftExt && PointerWidth == 32) { switch (SSELevel) { + case AVX2: + case AVX: case SSE42: case SSE41: case SSSE3: @@ -1917,6 +2110,30 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, } } +bool X86TargetInfo::hasFeature(StringRef Feature) const { + return llvm::StringSwitch<bool>(Feature) + .Case("aes", HasAES) + .Case("avx", SSELevel >= AVX) + .Case("avx2", SSELevel >= AVX2) + .Case("bmi", HasBMI) + .Case("bmi2", HasBMI2) + .Case("fma4", HasFMA4) + .Case("lzcnt", HasLZCNT) + .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) + .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon) + .Case("mmx", MMX3DNowLevel >= MMX) + .Case("popcnt", HasPOPCNT) + .Case("sse", SSELevel >= SSE1) + .Case("sse2", SSELevel >= SSE2) + .Case("sse3", SSELevel >= SSE3) + .Case("ssse3", SSELevel >= SSSE3) + .Case("sse41", SSELevel >= SSE41) + .Case("sse42", SSELevel >= SSE42) + .Case("x86", true) + .Case("x86_32", PointerWidth == 32) + .Case("x86_64", PointerWidth == 64) + .Default(false); +} bool X86TargetInfo::validateAsmConstraint(const char *&Name, @@ -1959,7 +2176,6 @@ X86TargetInfo::validateAsmConstraint(const char *&Name, // x86_64 instructions. return true; } - return false; } @@ -1992,6 +2208,7 @@ public: DoubleAlign = LongLongAlign = 32; LongDoubleWidth = 96; LongDoubleAlign = 32; + SuitableAlign = 128; 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:32:64-v64:64:64-v128:128:128-" "a0:0:64-f80:32:32-n8:16:32-S128"; @@ -2023,6 +2240,20 @@ public: } // end anonymous namespace namespace { +class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> { +public: + NetBSDI386TargetInfo(const std::string &triple) : + NetBSDTargetInfo<X86_32TargetInfo>(triple) { + } + + virtual unsigned getFloatEvalMethod() const { + // NetBSD defaults to "double" rounding + return 1; + } +}; +} // end anonymous namespace + +namespace { class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { public: OpenBSDI386TargetInfo(const std::string& triple) : @@ -2041,6 +2272,7 @@ public: DarwinTargetInfo<X86_32TargetInfo>(triple) { LongDoubleWidth = 128; LongDoubleAlign = 128; + SuitableAlign = 128; SizeType = UnsignedLong; IntPtrType = SignedLong; DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" @@ -2233,6 +2465,7 @@ public: LongDoubleAlign = 128; LargeArrayMinWidth = 128; LargeArrayAlign = 128; + SuitableAlign = 128; IntMaxType = SignedLong; UIntMaxType = UnsignedLong; Int64Type = SignedLong; @@ -2245,6 +2478,9 @@ public: // Use fpret only for long double. RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble); + // Use fp2ret for _Complex long double. + ComplexLongDoubleUsesFP2Ret = true; + // x86-64 has atomics up to 16 bytes. // FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128 // on CPUs with cmpxchg16b @@ -2399,8 +2635,11 @@ public: ARMTargetInfo(const std::string &TripleStr) : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s") { + BigEndian = false; SizeType = UnsignedInt; PtrDiffType = SignedInt; + // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int. + WCharType = UnsignedInt; // {} in inline assembly are neon specifiers, not assembly variant // specifiers. @@ -2426,6 +2665,12 @@ public: // ARM has atomics up to 8 bytes // FIXME: Set MaxAtomicInlineWidth if we have the feature v6e MaxAtomicPromoteWidth = 64; + + // Do force alignment of members that follow zero length bitfields. If + // the alignment of the zero-length bitfield is greater than the member + // that follows it, `bar', `bar' will be aligned as the type of the + // zero length bitfield. + UseZeroLengthBitfieldAlignment = true; } virtual const char *getABI() const { return ABI.c_str(); } virtual bool setABI(const std::string &Name) { @@ -2436,19 +2681,16 @@ public: // FIXME: We need support for -meabi... we could just mangle it into the // name. if (Name == "apcs-gnu") { - DoubleAlign = LongLongAlign = LongDoubleAlign = 32; + DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32; SizeType = UnsignedLong; + // Revert to using SignedInt on apcs-gnu to comply with existing behaviour. + WCharType = SignedInt; + // Do not respect the alignment of bit-field types when laying out // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc. UseBitFieldTypeAlignment = false; - /// Do force alignment of members that follow zero length bitfields. If - /// the alignment of the zero-length bitfield is greater than the member - /// that follows it, `bar', `bar' will be aligned as the type of the - /// zero length bitfield. - UseZeroLengthBitfieldAlignment = true; - /// gcc forces the alignment to 4 bytes, regardless of the type of the /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in /// gcc. @@ -2485,10 +2727,11 @@ public: } virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const { if (Name == "soft-float" || Name == "soft-float-abi" || - Name == "vfp2" || Name == "vfp3" || Name == "neon") { + Name == "vfp2" || Name == "vfp3" || Name == "neon" || Name == "d16" || + Name == "neonfp") { Features[Name] = Enabled; } else return false; @@ -2522,6 +2765,15 @@ public: Features.erase(it); } + virtual bool hasFeature(StringRef Feature) const { + return llvm::StringSwitch<bool>(Feature) + .Case("arm", true) + .Case("softfloat", SoftFloat) + .Case("thumb", IsThumb) + .Case("neon", FPU == NeonFPU && !SoftFloat && + StringRef(getCPUDefineSuffix(CPU)).startswith("7")) + .Default(false); + } static const char *getCPUDefineSuffix(StringRef Name) { return llvm::StringSwitch<const char*>(Name) .Cases("arm8", "arm810", "4") @@ -2540,6 +2792,7 @@ public: .Cases("arm1156t2-s", "arm1156t2f-s", "6T2") .Cases("cortex-a8", "cortex-a9", "7A") .Case("cortex-m3", "7M") + .Case("cortex-m4", "7M") .Case("cortex-m0", "6M") .Default(0); } @@ -2606,6 +2859,7 @@ public: Records = BuiltinInfo; NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin; } + virtual bool isCLZForZeroUndef() const { return false; } virtual const char *getVAListDeclaration() const { return "typedef void* __builtin_va_list;"; } @@ -2729,7 +2983,6 @@ const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { }; } // end anonymous namespace. - namespace { class DarwinARMTargetInfo : public DarwinTargetInfo<ARMTargetInfo> { @@ -2750,6 +3003,154 @@ public: }; } // end anonymous namespace. + +namespace { +// Hexagon abstract base class +class HexagonTargetInfo : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; + static const char * const GCCRegNames[]; + static const TargetInfo::GCCRegAlias GCCRegAliases[]; + std::string CPU; +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"); + + // {} in inline assembly are packet specifiers, not assembly variant + // specifiers. + NoAsmVariants = true; + } + + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + Records = BuiltinInfo; + NumRecords = clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin; + } + + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const { + return true; + } + + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const; + + virtual bool hasFeature(StringRef Feature) const { + return Feature == "hexagon"; + } + + virtual const char *getVAListDeclaration() const { + return "typedef char* __builtin_va_list;"; + } + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const; + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const; + virtual const char *getClobbers() const { + return ""; + } + + static const char *getHexagonCPUSuffix(StringRef Name) { + return llvm::StringSwitch<const char*>(Name) + .Case("hexagonv2", "2") + .Case("hexagonv3", "3") + .Case("hexagonv4", "4") + .Default(0); + } + + virtual bool setCPU(const std::string &Name) { + if (!getHexagonCPUSuffix(Name)) + return false; + + CPU = Name; + return true; + } +}; + +void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("qdsp6"); + Builder.defineMacro("__qdsp6", "1"); + Builder.defineMacro("__qdsp6__", "1"); + + Builder.defineMacro("hexagon"); + Builder.defineMacro("__hexagon", "1"); + Builder.defineMacro("__hexagon__", "1"); + + if(CPU == "hexagonv1") { + Builder.defineMacro("__HEXAGON_V1__"); + Builder.defineMacro("__HEXAGON_ARCH__", "1"); + if(Opts.HexagonQdsp6Compat) { + Builder.defineMacro("__QDSP6_V1__"); + Builder.defineMacro("__QDSP6_ARCH__", "1"); + } + } + else if(CPU == "hexagonv2") { + Builder.defineMacro("__HEXAGON_V2__"); + Builder.defineMacro("__HEXAGON_ARCH__", "2"); + if(Opts.HexagonQdsp6Compat) { + Builder.defineMacro("__QDSP6_V2__"); + Builder.defineMacro("__QDSP6_ARCH__", "2"); + } + } + else if(CPU == "hexagonv3") { + Builder.defineMacro("__HEXAGON_V3__"); + Builder.defineMacro("__HEXAGON_ARCH__", "3"); + if(Opts.HexagonQdsp6Compat) { + Builder.defineMacro("__QDSP6_V3__"); + Builder.defineMacro("__QDSP6_ARCH__", "3"); + } + } + else if(CPU == "hexagonv4") { + Builder.defineMacro("__HEXAGON_V4__"); + Builder.defineMacro("__HEXAGON_ARCH__", "4"); + if(Opts.HexagonQdsp6Compat) { + Builder.defineMacro("__QDSP6_V4__"); + Builder.defineMacro("__QDSP6_ARCH__", "4"); + } + } +} + +const char * const HexagonTargetInfo::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", + "p0", "p1", "p2", "p3", + "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp" +}; + +void HexagonTargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); +} + + +const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { + { { "sp" }, "r29" }, + { { "fp" }, "r30" }, + { { "lr" }, "r31" }, + }; + +void HexagonTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + Aliases = GCCRegAliases; + NumAliases = llvm::array_lengthof(GCCRegAliases); +} + + +const Builtin::Info HexagonTargetInfo::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/BuiltinsHexagon.def" +}; +} + + namespace { class SparcV8TargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; @@ -2758,11 +3159,12 @@ 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"; } virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, - const std::string &Name, + StringRef Name, bool Enabled) const { if (Name == "soft-float") Features[Name] = Enabled; @@ -2786,6 +3188,14 @@ public: if (SoftFloat) Builder.defineMacro("SOFT_FLOAT", "1"); } + + virtual bool hasFeature(StringRef Feature) const { + return llvm::StringSwitch<bool>(Feature) + .Case("softfloat", SoftFloat) + .Case("sparc", true) + .Default(false); + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { // FIXME: Implement! @@ -2887,11 +3297,13 @@ namespace { static const char * const GCCRegNames[]; public: MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { + BigEndian = false; TLSSupported = false; IntWidth = 16; IntAlign = 16; LongWidth = 32; LongLongWidth = 64; LongAlign = LongLongAlign = 16; PointerWidth = 16; PointerAlign = 16; + SuitableAlign = 16; SizeType = UnsignedInt; IntMaxType = SignedLong; UIntMaxType = UnsignedLong; @@ -2912,6 +3324,9 @@ namespace { Records = 0; NumRecords = 0; } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "msp430"; + } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, @@ -2947,140 +3362,6 @@ namespace { } } - -namespace { - class SystemZTargetInfo : public TargetInfo { - static const char * const GCCRegNames[]; - public: - SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) { - TLSSupported = false; - IntWidth = IntAlign = 32; - LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; - PointerWidth = PointerAlign = 64; - DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64"; - } - virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { - Builder.defineMacro("__s390__"); - Builder.defineMacro("__s390x__"); - } - 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 { - // FIXME: implement - return true; - } - virtual const char *getClobbers() const { - // FIXME: Is this really right? - return ""; - } - virtual const char *getVAListDeclaration() const { - // FIXME: implement - return "typedef char* __builtin_va_list;"; - } - }; - - const char * const SystemZTargetInfo::GCCRegNames[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" - }; - - void SystemZTargetInfo::getGCCRegNames(const char * const *&Names, - unsigned &NumNames) const { - Names = GCCRegNames; - NumNames = llvm::array_lengthof(GCCRegNames); - } -} - -namespace { - class BlackfinTargetInfo : public TargetInfo { - static const char * const GCCRegNames[]; - public: - BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) { - TLSSupported = false; - DoubleAlign = 32; - LongLongAlign = 32; - LongDoubleAlign = 32; - DescriptionString = "e-p:32:32-i64:32-f64:32-n32"; - } - - virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { - DefineStd(Builder, "bfin", Opts); - DefineStd(Builder, "BFIN", Opts); - Builder.defineMacro("__ADSPBLACKFIN__"); - // FIXME: This one is really dependent on -mcpu - Builder.defineMacro("__ADSPLPBLACKFIN__"); - // FIXME: Add cpu-dependent defines and __SILICON_REVISION__ - } - - 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 { - if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) { - Info.setAllowsRegister(); - return true; - } - return false; - } - - virtual const char *getClobbers() const { - return ""; - } - - virtual const char *getVAListDeclaration() const { - return "typedef char* __builtin_va_list;"; - } - }; - - const char * const BlackfinTargetInfo::GCCRegNames[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp", - "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3", - "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3", - "a0", "a1", "cc", - "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp", - "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1" - }; - - void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names, - unsigned &NumNames) const { - Names = GCCRegNames; - NumNames = llvm::array_lengthof(GCCRegNames); - } -} - namespace { // LLVM and Clang cannot be used directly to output native binaries for @@ -3107,6 +3388,7 @@ namespace { IntAlign = 32; LongAlign = LongLongAlign = 32; PointerAlign = 32; + SuitableAlign = 32; SizeType = UnsignedInt; IntMaxType = SignedLong; UIntMaxType = UnsignedLong; @@ -3134,6 +3416,10 @@ namespace { Builder.defineMacro("__TCE__"); Builder.defineMacro("__TCE_V1__"); } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "tce"; + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const {} virtual const char *getClobbers() const { @@ -3156,14 +3442,22 @@ namespace { namespace { class MipsTargetInfoBase : public TargetInfo { std::string CPU; + bool SoftFloat; + bool SingleFloat; + protected: std::string ABI; + public: - MipsTargetInfoBase(const std::string& triple, const std::string& ABIStr) - : TargetInfo(triple), ABI(ABIStr) { - SizeType = UnsignedInt; - PtrDiffType = SignedInt; - } + MipsTargetInfoBase(const std::string& triple, + const std::string& ABIStr, + const std::string& CPUStr) + : TargetInfo(triple), + CPU(CPUStr), + SoftFloat(false), SingleFloat(false), + ABI(ABIStr) + {} + virtual const char *getABI() const { return ABI.c_str(); } virtual bool setABI(const std::string &Name) = 0; virtual bool setCPU(const std::string &Name) { @@ -3174,28 +3468,50 @@ public: Features[ABI] = true; Features[CPU] = true; } + virtual void getArchDefines(const LangOptions &Opts, - MacroBuilder &Builder) const = 0; + 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) + Builder.defineMacro("__mips_hard_float", Twine(1)); + else + llvm_unreachable("Invalid float ABI for Mips."); + + Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0))); + Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth())); + Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth())); + } + virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const = 0; virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { // FIXME: Implement! } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "mips"; + } virtual const char *getVAListDeclaration() const { return "typedef void* __builtin_va_list;"; } virtual void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const { static const char * const GCCRegNames[] = { + // CPU register names + // Must match second column of GCCRegAliases "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", - "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31", + "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", + // Floating point register names "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", + // Hi/lo and condition register names "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", "$fcc5","$fcc6","$fcc7" }; @@ -3208,26 +3524,64 @@ public: TargetInfo::ConstraintInfo &Info) const { switch (*Name) { default: + return false; + case 'r': // CPU registers. case 'd': // Equivalent to "r" unless generating MIPS16 code. case 'y': // Equivalent to "r", backwards compatibility only. case 'f': // floating-point registers. + case 'c': // $25 for indirect jumps + case 'l': // lo register + case 'x': // hilo register pair Info.setAllowsRegister(); return true; } - return false; } virtual const char *getClobbers() const { // FIXME: Implement! return ""; } + + virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, + bool Enabled) const { + if (Name == "soft-float" || Name == "single-float") { + Features[Name] = Enabled; + return true; + } + return false; + } + + virtual void HandleTargetFeatures(std::vector<std::string> &Features) { + SoftFloat = false; + SingleFloat = false; + + 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; + } + } + } }; class Mips32TargetInfoBase : public MipsTargetInfoBase { public: Mips32TargetInfoBase(const std::string& triple) : - MipsTargetInfoBase(triple, "o32") {} + MipsTargetInfoBase(triple, "o32", "mips32") { + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + } virtual bool setABI(const std::string &Name) { if ((Name == "o32") || (Name == "eabi")) { ABI = Name; @@ -3237,6 +3591,8 @@ public: } virtual void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const { + MipsTargetInfoBase::getArchDefines(Opts, Builder); + if (ABI == "o32") { Builder.defineMacro("__mips_o32"); Builder.defineMacro("_ABIO32", "1"); @@ -3278,8 +3634,8 @@ public: { { "k0" }, "$26" }, { { "k1" }, "$27" }, { { "gp" }, "$28" }, - { { "sp" }, "$29" }, - { { "fp" }, "$30" }, + { { "sp","$sp" }, "$29" }, + { { "fp","$fp" }, "$30" }, { { "ra" }, "$31" } }; Aliases = GCCRegAliases; @@ -3307,6 +3663,7 @@ public: class Mips32ELTargetInfo : public Mips32TargetInfoBase { public: Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { + BigEndian = false; DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; } @@ -3325,17 +3682,32 @@ class Mips64TargetInfoBase : public MipsTargetInfoBase { virtual void SetDescriptionString(const std::string &Name) = 0; public: Mips64TargetInfoBase(const std::string& triple) : - MipsTargetInfoBase(triple, "n64") {} + MipsTargetInfoBase(triple, "n64", "mips64") { + LongWidth = LongAlign = 64; + PointerWidth = PointerAlign = 64; + LongDoubleWidth = LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad; + SuitableAlign = 128; + } virtual bool setABI(const std::string &Name) { SetDescriptionString(Name); - if ((Name == "n32") || (Name == "n64")) { - ABI = Name; - return true; - } else + + if (Name != "n32" && Name != "n64") return false; + + ABI = Name; + + if (Name == "n32") { + LongWidth = LongAlign = 32; + PointerWidth = PointerAlign = 32; + } + + return true; } virtual void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const { + MipsTargetInfoBase::getArchDefines(Opts, Builder); + if (ABI == "n32") { Builder.defineMacro("__mips_n32"); Builder.defineMacro("_ABIN32", "2"); @@ -3380,8 +3752,8 @@ public: { { "k0" }, "$26" }, { { "k1" }, "$27" }, { { "gp" }, "$28" }, - { { "sp" }, "$29" }, - { { "fp" }, "$30" }, + { { "sp","$sp" }, "$29" }, + { { "fp","$fp" }, "$30" }, { { "ra" }, "$31" } }; Aliases = GCCRegAliases; @@ -3394,13 +3766,15 @@ class Mips64EBTargetInfo : public Mips64TargetInfoBase { // Change DescriptionString only if ABI is n32. if (Name == "n32") DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" + "v64:64:64-n32"; } public: Mips64EBTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { // Default ABI is n64. DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" + "v64:64:64-n32"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -3418,13 +3792,16 @@ class Mips64ELTargetInfo : public Mips64TargetInfoBase { // Change DescriptionString only if ABI is n32. if (Name == "n32") DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + "i64:64:64-f32:32:32-f64:64:64-f128:128:128" + "-v64:64:64-n32"; } public: Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { - // Default ABI is n64. + // Default ABI is n64. + BigEndian = false; DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" + "v64:64:64-n32"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -3442,6 +3819,7 @@ namespace { class PNaClTargetInfo : public TargetInfo { public: PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) { + BigEndian = false; this->UserLabelPrefix = ""; this->LongAlign = 32; this->LongWidth = 32; @@ -3477,9 +3855,13 @@ public: if (Opts.CPlusPlus) Builder.defineMacro("_GNU_SOURCE"); + Builder.defineMacro("__LITTLE_ENDIAN__"); Builder.defineMacro("__native_client__"); getArchDefines(Opts, Builder); } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "pnacl"; + } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { } @@ -3526,6 +3908,9 @@ static TargetInfo *AllocateTarget(const std::string &T) { default: return NULL; + case llvm::Triple::hexagon: + return new HexagonTargetInfo(T); + case llvm::Triple::arm: case llvm::Triple::thumb: if (Triple.isOSDarwin()) @@ -3544,11 +3929,6 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new ARMTargetInfo(T); } - case llvm::Triple::bfin: - if ( os == llvm::Triple::RTEMS ) - return new RTEMSTargetInfo<BlackfinTargetInfo>(T); - return new BlackfinTargetInfo(T); - case llvm::Triple::msp430: return new MSP430TargetInfo(T); @@ -3676,9 +4056,6 @@ static TargetInfo *AllocateTarget(const std::string &T) { case llvm::Triple::cellspu: return new PS3SPUTargetInfo<PPC64TargetInfo>(T); - case llvm::Triple::systemz: - return new SystemZTargetInfo(T); - case llvm::Triple::tce: return new TCETargetInfo(T); @@ -3694,7 +4071,7 @@ static TargetInfo *AllocateTarget(const std::string &T) { case llvm::Triple::DragonFly: return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<X86_32TargetInfo>(T); + return new NetBSDI386TargetInfo(T); case llvm::Triple::OpenBSD: return new OpenBSDI386TargetInfo(T); case llvm::Triple::FreeBSD: @@ -3753,7 +4130,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, llvm::Triple Triple(Opts.Triple); // Construct the target - llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); + OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); if (!Target) { Diags.Report(diag::err_target_unknown_triple) << Triple.str(); return 0; @@ -3821,8 +4198,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, Opts.Features.clear(); for (llvm::StringMap<bool>::const_iterator it = Features.begin(), ie = Features.end(); it != ie; ++it) - Opts.Features.push_back(std::string(it->second ? "+" : "-") + - it->first().str()); + Opts.Features.push_back((it->second ? "+" : "-") + it->first().str()); Target->HandleTargetFeatures(Opts.Features); return Target.take(); diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp index 526b2b4..36138ac 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Version.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Version.cpp @@ -19,7 +19,7 @@ #include <cstdlib> namespace clang { - + std::string getClangRepositoryPath() { #if defined(CLANG_REPOSITORY_STRING) return CLANG_REPOSITORY_STRING; @@ -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/tags/RELEASE_30/final/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")); @@ -50,6 +50,23 @@ std::string getClangRepositoryPath() { #endif } +std::string getLLVMRepositoryPath() { +#ifdef LLVM_REPOSITORY + StringRef URL(LLVM_REPOSITORY); +#else + StringRef URL(""); +#endif + + // Trim path prefix off, assuming path came from standard llvm path. + // Leave "llvm/" prefix to distinguish the following llvm revision from the + // clang revision. + size_t Start = URL.find("llvm/"); + if (Start != StringRef::npos) + URL = URL.substr(Start); + + return URL; +} + std::string getClangRevision() { #ifdef SVN_REVISION return SVN_REVISION; @@ -58,29 +75,50 @@ std::string getClangRevision() { #endif } +std::string getLLVMRevision() { +#ifdef LLVM_REVISION + return LLVM_REVISION; +#else + return ""; +#endif +} + std::string getClangFullRepositoryVersion() { std::string buf; llvm::raw_string_ostream OS(buf); std::string Path = getClangRepositoryPath(); std::string Revision = getClangRevision(); - if (!Path.empty()) - OS << Path; - if (!Revision.empty()) { + if (!Path.empty() || !Revision.empty()) { + OS << '('; if (!Path.empty()) - OS << ' '; - OS << Revision; + OS << Path; + if (!Revision.empty()) { + if (!Path.empty()) + OS << ' '; + OS << Revision; + } + OS << ')'; + } + // Support LLVM in a separate repository. + std::string LLVMRev = getLLVMRevision(); + if (!LLVMRev.empty() && LLVMRev != Revision) { + OS << " ("; + std::string LLVMRepo = getLLVMRepositoryPath(); + if (!LLVMRepo.empty()) + OS << LLVMRepo << ' '; + OS << LLVMRev << ')'; } return OS.str(); } - + std::string getClangFullVersion() { std::string buf; llvm::raw_string_ostream OS(buf); #ifdef CLANG_VENDOR OS << CLANG_VENDOR; #endif - OS << "clang version " CLANG_VERSION_STRING " (" - << getClangFullRepositoryVersion() << ')'; + OS << "clang version " CLANG_VERSION_STRING " " + << getClangFullRepositoryVersion(); #ifdef CLANG_VENDOR_SUFFIX OS << CLANG_VENDOR_SUFFIX; |