diff options
Diffstat (limited to 'tools/libclang/CIndex.cpp')
-rw-r--r-- | tools/libclang/CIndex.cpp | 344 |
1 files changed, 310 insertions, 34 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index f4d347108c9ff..499d9abf9a8ef 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -26,6 +26,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticCategories.h" #include "clang/Basic/DiagnosticIDs.h" +#include "clang/Basic/Stack.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" @@ -103,7 +104,7 @@ cxtu::CXTUOwner::~CXTUOwner() { clang_disposeTranslationUnit(TU); } -/// \brief Compare two source ranges to determine their relative position in +/// Compare two source ranges to determine their relative position in /// the translation unit. static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1, @@ -119,7 +120,7 @@ static RangeComparisonResult RangeCompare(SourceManager &SM, return RangeOverlap; } -/// \brief Determine if a source location falls within, before, or after a +/// Determine if a source location falls within, before, or after a /// a given source range. static RangeComparisonResult LocationCompare(SourceManager &SM, SourceLocation L, SourceRange R) { @@ -134,7 +135,7 @@ static RangeComparisonResult LocationCompare(SourceManager &SM, return RangeOverlap; } -/// \brief Translate a Clang source range into a CIndex source range. +/// Translate a Clang source range into a CIndex source range. /// /// Clang internally represents ranges where the end location points to the /// start of the token at the end. However, for external clients it is more @@ -146,9 +147,13 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM, // We want the last character in this location, so we will adjust the // location accordingly. SourceLocation EndLoc = R.getEnd(); - if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc)) - EndLoc = SM.getExpansionRange(EndLoc).second; - if (R.isTokenRange() && EndLoc.isValid()) { + bool IsTokenRange = R.isTokenRange(); + if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc)) { + CharSourceRange Expansion = SM.getExpansionRange(EndLoc); + EndLoc = Expansion.getEnd(); + IsTokenRange = Expansion.isTokenRange(); + } + if (IsTokenRange && EndLoc.isValid()) { unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts); EndLoc = EndLoc.getLocWithOffset(Length); @@ -174,7 +179,7 @@ RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) { return RangeCompare(AU->getSourceManager(), R, RegionOfInterest); } -/// \brief Visit the given cursor and, if requested by the visitor, +/// Visit the given cursor and, if requested by the visitor, /// its children. /// /// \param Cursor the cursor to visit. @@ -478,7 +483,7 @@ bool CursorVisitor::visitPreprocessedEntities(InputIterator First, return false; } -/// \brief Visit the children of the given cursor. +/// Visit the children of the given cursor. /// /// \returns true if the visitation should be aborted, false if it /// should continue. @@ -785,7 +790,17 @@ bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { return false; } -/// \brief Compare two base or member initializers based on their source order. +static bool HasTrailingReturnType(FunctionDecl *ND) { + const QualType Ty = ND->getType(); + if (const FunctionType *AFT = Ty->getAs<FunctionType>()) { + if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT)) + return FT->hasTrailingReturn(); + } + + return false; +} + +/// Compare two base or member initializers based on their source order. static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X, CXXCtorInitializer *const *Y) { return (*X)->getSourceOrder() - (*Y)->getSourceOrder(); @@ -804,14 +819,16 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { // written. This requires a bit of work. TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>(); + const bool HasTrailingRT = HasTrailingReturnType(ND); // If we have a function declared directly (without the use of a typedef), // visit just the return type. Otherwise, just visit the function's type // now. - if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) || + if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT && + Visit(FTL.getReturnLoc())) || (!FTL && Visit(TL))) return true; - + // Visit the nested-name-specifier, if present. if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc()) if (VisitNestedNameSpecifierLoc(QualifierLoc)) @@ -827,7 +844,11 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { // Visit the function parameters, if we have a function type. if (FTL && VisitFunctionTypeLoc(FTL, true)) return true; - + + // Visit the function's trailing return type. + if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc())) + return true; + // FIXME: Attributes? } @@ -1023,8 +1044,8 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { } // Now sort the Decls so that they appear in lexical order. - std::sort(DeclsInContainer.begin(), DeclsInContainer.end(), - [&SM](Decl *A, Decl *B) { + llvm::sort(DeclsInContainer.begin(), DeclsInContainer.end(), + [&SM](Decl *A, Decl *B) { SourceLocation L_A = A->getLocStart(); SourceLocation L_B = B->getLocStart(); return L_A != L_B ? @@ -1751,6 +1772,7 @@ DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType) DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType) DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType) DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type) +DEFAULT_TYPELOC_IMPL(DependentVector, Type) DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type) DEFAULT_TYPELOC_IMPL(Vector, Type) DEFAULT_TYPELOC_IMPL(ExtVector, VectorType) @@ -1780,7 +1802,7 @@ bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) { bool CursorVisitor::VisitAttributes(Decl *D) { for (const auto *I : D->attrs()) - if (Visit(MakeCXCursor(I, D, TU))) + if (!I->isImplicit() && Visit(MakeCXCursor(I, D, TU))) return true; return false; @@ -2099,7 +2121,7 @@ void EnqueueVisitor::EnqueueChildren(const Stmt *S) { namespace { class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> { EnqueueVisitor *Visitor; - /// \brief Process clauses with list of variables. + /// Process clauses with list of variables. template <typename T> void VisitOMPClauseList(T *Node); public: @@ -2577,7 +2599,7 @@ void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) { return; // Ignore base anonymous struct/union fields, otherwise they will shadow the - // real field that that we are interested in. + // real field that we are interested in. if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) { if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) { if (FD->isAnonymousStructOrUnion()) { @@ -3360,9 +3382,15 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename, = options & CXTranslationUnit_CacheCompletionResults; bool IncludeBriefCommentsInCodeCompletion = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; - bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies; bool SingleFileParse = options & CXTranslationUnit_SingleFileParse; bool ForSerialization = options & CXTranslationUnit_ForSerialization; + SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None; + if (options & CXTranslationUnit_SkipFunctionBodies) { + SkipFunctionBodies = + (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble) + ? SkipFunctionBodiesScope::Preamble + : SkipFunctionBodiesScope::PreambleAndMainFile; + } // Configure the diagnostics. IntrusiveRefCntPtr<DiagnosticsEngine> @@ -4233,6 +4261,14 @@ int clang_File_isEqual(CXFile file1, CXFile file2) { return FEnt1->getUniqueID() == FEnt2->getUniqueID(); } +CXString clang_File_tryGetRealPathName(CXFile SFile) { + if (!SFile) + return cxstring::createNull(); + + FileEntry *FEnt = static_cast<FileEntry *>(SFile); + return cxstring::createRef(FEnt->tryGetRealPathName()); +} + //===----------------------------------------------------------------------===// // CXCursor Operations. //===----------------------------------------------------------------------===// @@ -4690,6 +4726,195 @@ CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) { return cxstring::createSet(Manglings); } +CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) { + if (clang_Cursor_isNull(C)) + return 0; + return new PrintingPolicy(getCursorContext(C).getPrintingPolicy()); +} + +void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) { + if (Policy) + delete static_cast<PrintingPolicy *>(Policy); +} + +unsigned +clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy, + enum CXPrintingPolicyProperty Property) { + if (!Policy) + return 0; + + PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy); + switch (Property) { + case CXPrintingPolicy_Indentation: + return P->Indentation; + case CXPrintingPolicy_SuppressSpecifiers: + return P->SuppressSpecifiers; + case CXPrintingPolicy_SuppressTagKeyword: + return P->SuppressTagKeyword; + case CXPrintingPolicy_IncludeTagDefinition: + return P->IncludeTagDefinition; + case CXPrintingPolicy_SuppressScope: + return P->SuppressScope; + case CXPrintingPolicy_SuppressUnwrittenScope: + return P->SuppressUnwrittenScope; + case CXPrintingPolicy_SuppressInitializers: + return P->SuppressInitializers; + case CXPrintingPolicy_ConstantArraySizeAsWritten: + return P->ConstantArraySizeAsWritten; + case CXPrintingPolicy_AnonymousTagLocations: + return P->AnonymousTagLocations; + case CXPrintingPolicy_SuppressStrongLifetime: + return P->SuppressStrongLifetime; + case CXPrintingPolicy_SuppressLifetimeQualifiers: + return P->SuppressLifetimeQualifiers; + case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors: + return P->SuppressTemplateArgsInCXXConstructors; + case CXPrintingPolicy_Bool: + return P->Bool; + case CXPrintingPolicy_Restrict: + return P->Restrict; + case CXPrintingPolicy_Alignof: + return P->Alignof; + case CXPrintingPolicy_UnderscoreAlignof: + return P->UnderscoreAlignof; + case CXPrintingPolicy_UseVoidForZeroParams: + return P->UseVoidForZeroParams; + case CXPrintingPolicy_TerseOutput: + return P->TerseOutput; + case CXPrintingPolicy_PolishForDeclaration: + return P->PolishForDeclaration; + case CXPrintingPolicy_Half: + return P->Half; + case CXPrintingPolicy_MSWChar: + return P->MSWChar; + case CXPrintingPolicy_IncludeNewlines: + return P->IncludeNewlines; + case CXPrintingPolicy_MSVCFormatting: + return P->MSVCFormatting; + case CXPrintingPolicy_ConstantsAsWritten: + return P->ConstantsAsWritten; + case CXPrintingPolicy_SuppressImplicitBase: + return P->SuppressImplicitBase; + case CXPrintingPolicy_FullyQualifiedName: + return P->FullyQualifiedName; + } + + assert(false && "Invalid CXPrintingPolicyProperty"); + return 0; +} + +void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, + enum CXPrintingPolicyProperty Property, + unsigned Value) { + if (!Policy) + return; + + PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy); + switch (Property) { + case CXPrintingPolicy_Indentation: + P->Indentation = Value; + return; + case CXPrintingPolicy_SuppressSpecifiers: + P->SuppressSpecifiers = Value; + return; + case CXPrintingPolicy_SuppressTagKeyword: + P->SuppressTagKeyword = Value; + return; + case CXPrintingPolicy_IncludeTagDefinition: + P->IncludeTagDefinition = Value; + return; + case CXPrintingPolicy_SuppressScope: + P->SuppressScope = Value; + return; + case CXPrintingPolicy_SuppressUnwrittenScope: + P->SuppressUnwrittenScope = Value; + return; + case CXPrintingPolicy_SuppressInitializers: + P->SuppressInitializers = Value; + return; + case CXPrintingPolicy_ConstantArraySizeAsWritten: + P->ConstantArraySizeAsWritten = Value; + return; + case CXPrintingPolicy_AnonymousTagLocations: + P->AnonymousTagLocations = Value; + return; + case CXPrintingPolicy_SuppressStrongLifetime: + P->SuppressStrongLifetime = Value; + return; + case CXPrintingPolicy_SuppressLifetimeQualifiers: + P->SuppressLifetimeQualifiers = Value; + return; + case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors: + P->SuppressTemplateArgsInCXXConstructors = Value; + return; + case CXPrintingPolicy_Bool: + P->Bool = Value; + return; + case CXPrintingPolicy_Restrict: + P->Restrict = Value; + return; + case CXPrintingPolicy_Alignof: + P->Alignof = Value; + return; + case CXPrintingPolicy_UnderscoreAlignof: + P->UnderscoreAlignof = Value; + return; + case CXPrintingPolicy_UseVoidForZeroParams: + P->UseVoidForZeroParams = Value; + return; + case CXPrintingPolicy_TerseOutput: + P->TerseOutput = Value; + return; + case CXPrintingPolicy_PolishForDeclaration: + P->PolishForDeclaration = Value; + return; + case CXPrintingPolicy_Half: + P->Half = Value; + return; + case CXPrintingPolicy_MSWChar: + P->MSWChar = Value; + return; + case CXPrintingPolicy_IncludeNewlines: + P->IncludeNewlines = Value; + return; + case CXPrintingPolicy_MSVCFormatting: + P->MSVCFormatting = Value; + return; + case CXPrintingPolicy_ConstantsAsWritten: + P->ConstantsAsWritten = Value; + return; + case CXPrintingPolicy_SuppressImplicitBase: + P->SuppressImplicitBase = Value; + return; + case CXPrintingPolicy_FullyQualifiedName: + P->FullyQualifiedName = Value; + return; + } + + assert(false && "Invalid CXPrintingPolicyProperty"); +} + +CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) { + if (clang_Cursor_isNull(C)) + return cxstring::createEmpty(); + + if (clang_isDeclaration(C.kind)) { + const Decl *D = getCursorDecl(C); + if (!D) + return cxstring::createEmpty(); + + SmallString<128> Str; + llvm::raw_svector_ostream OS(Str); + PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy); + D->print(OS, UserPolicy ? *UserPolicy + : getCursorContext(C).getPrintingPolicy()); + + return cxstring::createDup(OS.str()); + } + + return cxstring::createEmpty(); +} + CXString clang_getCursorDisplayName(CXCursor C) { if (!clang_isDeclaration(C.kind)) return clang_getCursorSpelling(C); @@ -4838,6 +5063,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("VariableRef"); case CXCursor_IntegerLiteral: return cxstring::createRef("IntegerLiteral"); + case CXCursor_FixedPointLiteral: + return cxstring::createRef("FixedPointLiteral"); case CXCursor_FloatingLiteral: return cxstring::createRef("FloatingLiteral"); case CXCursor_ImaginaryLiteral: @@ -5421,6 +5648,15 @@ unsigned clang_isDeclaration(enum CXCursorKind K) { (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl); } +unsigned clang_isInvalidDeclaration(CXCursor C) { + if (clang_isDeclaration(C.kind)) { + if (const Decl *D = getCursorDecl(C)) + return D->isInvalidDecl(); + } + + return 0; +} + unsigned clang_isReference(enum CXCursorKind K) { return K >= CXCursor_FirstRef && K <= CXCursor_LastRef; } @@ -5727,7 +5963,7 @@ static SourceRange getRawCursorExtent(CXCursor C) { return SourceRange(); } -/// \brief Retrieves the "raw" cursor extent, which is then extended to include +/// Retrieves the "raw" cursor extent, which is then extended to include /// the decl-specifier-seq for declarations. static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) { if (clang_isDeclaration(C.kind)) { @@ -6420,6 +6656,42 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range, } while (Lex.getBufferLocation() < EffectiveBufferEnd); } +CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) { + LOG_FUNC_SECTION { + *Log << TU << ' ' << Location; + } + + if (isNotUsableTU(TU)) { + LOG_BAD_TU(TU); + return NULL; + } + + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); + if (!CXXUnit) + return NULL; + + SourceLocation Begin = cxloc::translateSourceLocation(Location); + if (Begin.isInvalid()) + return NULL; + SourceManager &SM = CXXUnit->getSourceManager(); + std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin); + DecomposedEnd.second += Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts()); + + SourceLocation End = SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second); + + SmallVector<CXToken, 32> CXTokens; + getTokens(CXXUnit, SourceRange(Begin, End), CXTokens); + + if (CXTokens.empty()) + return NULL; + + CXTokens.resize(1); + CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken))); + + memmove(Token, CXTokens.data(), sizeof(CXToken)); + return Token; +} + void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens, unsigned *NumTokens) { LOG_FUNC_SECTION { @@ -6452,7 +6724,8 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, if (CXTokens.empty()) return; - *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size()); + *Tokens = static_cast<CXToken *>( + llvm::safe_malloc(sizeof(CXToken) * CXTokens.size())); memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); *NumTokens = CXTokens.size(); } @@ -6536,7 +6809,7 @@ public: bool postVisitChildren(CXCursor cursor); void AnnotateTokens(); - /// \brief Determine whether the annotator saw any cursors that have + /// Determine whether the annotator saw any cursors that have /// context-sensitive keywords. bool hasContextSensitiveKeywords() const { return HasContextSensitiveKeywords; @@ -6561,7 +6834,7 @@ static inline void updateCursorAnnotation(CXCursor &Cursor, Cursor = updateC; } -/// \brief It annotates and advances tokens with a cursor until the comparison +/// It annotates and advances tokens with a cursor until the comparison //// between the cursor location and the source range is the same as /// \arg compResult. /// @@ -6586,7 +6859,7 @@ void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC, } } -/// \brief Special annotation handling for macro argument tokens. +/// Special annotation handling for macro argument tokens. /// \returns true if it advanced beyond all macro tokens, false otherwise. bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens( CXCursor updateC, @@ -6830,7 +7103,7 @@ static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor, namespace { -/// \brief Uses the macro expansions in the preprocessing record to find +/// Uses the macro expansions in the preprocessing record to find /// and mark tokens that are macro arguments. This info is used by the /// AnnotateTokensWorker. class MarkMacroArgTokensVisitor { @@ -6905,7 +7178,7 @@ MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent, parent); } -/// \brief Used by \c annotatePreprocessorTokens. +/// Used by \c annotatePreprocessorTokens. /// \returns true if lexing was finished, false otherwise. static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx, unsigned NumTokens) { @@ -7358,10 +7631,10 @@ static void getCursorPlatformAvailabilityForDecl( if (AvailabilityAttrs.empty()) return; - std::sort(AvailabilityAttrs.begin(), AvailabilityAttrs.end(), - [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) { - return LHS->getPlatform()->getName() < - RHS->getPlatform()->getName(); + llvm::sort(AvailabilityAttrs.begin(), AvailabilityAttrs.end(), + [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) { + return LHS->getPlatform()->getName() < + RHS->getPlatform()->getName(); }); ASTContext &Ctx = D->getASTContext(); auto It = std::unique( @@ -7479,8 +7752,8 @@ CXTLSKind clang_getCursorTLSKind(CXCursor cursor) { return CXTLS_None; } - /// \brief If the given cursor is the "templated" declaration - /// descibing a class or function template, return the class or + /// If the given cursor is the "templated" declaration + /// describing a class or function template, return the class or /// function template. static const Decl *maybeGetTemplateCursor(const Decl *D) { if (!D) @@ -8135,6 +8408,7 @@ CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) { SourceManager &sm = Ctx.getSourceManager(); FileEntry *fileEntry = static_cast<FileEntry *>(file); FileID wantedFileID = sm.translateFile(fileEntry); + bool isMainFile = wantedFileID == sm.getMainFileID(); const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges(); std::vector<SourceRange> wantedRanges; @@ -8142,6 +8416,8 @@ CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) { i != ei; ++i) { if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID) wantedRanges.push_back(*i); + else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) || astUnit->isInPreambleFileID(i->getEnd()))) + wantedRanges.push_back(*i); } skipped->count = wantedRanges.size(); @@ -8200,8 +8476,8 @@ void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) { // Misc. utility functions. //===----------------------------------------------------------------------===// -/// Default to using an 8 MB stack size on "safety" threads. -static unsigned SafetyStackThreadSize = 8 << 20; +/// Default to using our desired 8 MB stack size on "safety" threads. +static unsigned SafetyStackThreadSize = DesiredStackSize; namespace clang { @@ -8246,7 +8522,7 @@ void cxindex::printDiagsToStderr(ASTUnit *Unit) { fprintf(stderr, "%s\n", clang_getCString(Msg)); clang_disposeString(Msg); } -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 // On Windows, force a flush, since there may be multiple copies of // stderr and stdout in the file system, all with different buffers // but writing to the same device. |