// #pragma GCC visibility comes in two variants: // 'push' '(' [visibility] ')' // 'pop' void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &VisTok) { SourceLocation VisLoc = VisTok.getLocation(); Token Tok; PP.Lex(Tok); const IdentifierInfo *PushPop = Tok.getIdentifierInfo(); bool IsPush; const IdentifierInfo *VisType; if (PushPop && PushPop->isStr("pop")) { IsPush = false; VisType = 0; } else if (PushPop && PushPop->isStr("push")) { IsPush = true; PP.Lex(Tok); if (Tok.isNot(tok::l_paren)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "visibility"; return; } PP.Lex(Tok); VisType = Tok.getIdentifierInfo(); if (!VisType) { PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "visibility"; return; } PP.Lex(Tok); if (Tok.isNot(tok::r_paren)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "visibility"; return; } } else { PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "visibility"; return; } PP.Lex(Tok); if (Tok.isNot(tok::eom)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "visibility"; return; } Actions.ActOnPragmaVisibility(IsPush, VisType, VisLoc); }
/// AddImplicitIncludePTH - Add an implicit \#include using the original file /// used to generate a PTH cache. static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP, StringRef ImplicitIncludePTH) { PTHManager *P = PP.getPTHManager(); // Null check 'P' in the corner case where it couldn't be created. const char *OriginalFile = P ? P->getOriginalSourceFile() : nullptr; if (!OriginalFile) { PP.getDiagnostics().Report(diag::err_fe_pth_file_has_no_source_header) << ImplicitIncludePTH; return; } AddImplicitInclude(Builder, OriginalFile); }
/// InclusionRewriterInInput - Implement -frewrite-includes mode. void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts) { SourceManager &SM = PP.getSourceManager(); InclusionRewriter *Rewrite = new InclusionRewriter( PP, *OS, Opts.ShowLineMarkers, Opts.UseLineDirectives); Rewrite->detectMainFileEOL(); PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Rewrite)); PP.IgnorePragmas(); // First let the preprocessor process the entire file and call callbacks. // Callbacks will record which #include's were actually performed. PP.EnterMainSourceFile(); Token Tok; // Only preprocessor directives matter here, so disable macro expansion // everywhere else as an optimization. // TODO: It would be even faster if the preprocessor could be switched // to a mode where it would parse only preprocessor directives and comments, // nothing else matters for parsing or processing. PP.SetMacroExpansionOnlyInDirectives(); do { PP.Lex(Tok); if (Tok.is(tok::annot_module_begin)) Rewrite->handleModuleBegin(Tok); } while (Tok.isNot(tok::eof)); Rewrite->setPredefinesBuffer(SM.getBuffer(PP.getPredefinesFileID())); Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User); Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User); OS->flush(); }
/// \brief Handle '#pragma omp ...' when OpenMP is disabled. /// void PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &FirstTok) { if (PP.getDiagnostics().getDiagnosticLevel(diag::warn_pragma_omp_ignored, FirstTok.getLocation()) != DiagnosticsEngine::Ignored) { PP.Diag(FirstTok, diag::warn_pragma_omp_ignored); PP.getDiagnostics().setDiagnosticMapping(diag::warn_pragma_omp_ignored, diag::MAP_IGNORE, SourceLocation()); } PP.DiscardUntilEndOfDirective(); }
static void emitPremigrationErrors(const CapturedDiagList &arcDiags, DiagnosticOptions *diagOpts, Preprocessor &PP) { TextDiagnosticPrinter printer(llvm::errs(), diagOpts); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, diagOpts, &printer, /*ShouldOwnClient=*/false)); Diags->setSourceManager(&PP.getSourceManager()); printer.BeginSourceFile(PP.getLangOpts(), &PP); arcDiags.reportDiagnostics(*Diags); printer.EndSourceFile(); }
bool TokenLexer::MaybeRemoveCommaBeforeVaArgs( SmallVectorImpl<Token> &ResultToks, bool HasPasteOperator, MacroInfo *Macro, unsigned MacroArgNo, Preprocessor &PP) { // Is the macro argument __VA_ARGS__? if (!Macro->isVariadic() || MacroArgNo != Macro->getNumArgs()-1) return false; // In Microsoft-compatibility mode, a comma is removed in the expansion // of " ... , __VA_ARGS__ " if __VA_ARGS__ is empty. This extension is // not supported by gcc. if (!HasPasteOperator && !PP.getLangOpts().MSVCCompat) return false; // GCC removes the comma in the expansion of " ... , ## __VA_ARGS__ " if // __VA_ARGS__ is empty, but not in strict C99 mode where there are no // named arguments, where it remains. In all other modes, including C99 // with GNU extensions, it is removed regardless of named arguments. // Microsoft also appears to support this extension, unofficially. if (PP.getLangOpts().C99 && !PP.getLangOpts().GNUMode && Macro->getNumArgs() < 2) return false; // Is a comma available to be removed? if (ResultToks.empty() || !ResultToks.back().is(tok::comma)) return false; // Issue an extension diagnostic for the paste operator. if (HasPasteOperator) PP.Diag(ResultToks.back().getLocation(), diag::ext_paste_comma); // Remove the comma. ResultToks.pop_back(); if (!ResultToks.empty()) { // If the comma was right after another paste (e.g. "X##,##__VA_ARGS__"), // then removal of the comma should produce a placemarker token (in C99 // terms) which we model by popping off the previous ##, giving us a plain // "X" when __VA_ARGS__ is empty. if (ResultToks.back().is(tok::hashhash)) ResultToks.pop_back(); // Remember that this comma was elided. ResultToks.back().setFlag(Token::CommaAfterElided); } // Never add a space, even if the comma, ##, or arg had a space. NextTokGetsSpace = false; return true; }
/// InitializePreprocessor - Initialize the preprocessor getting it and the /// environment ready to process a single file. This returns true on error. /// bool InitializePreprocessor(Preprocessor &PP, const PreprocessorInitOptions& InitOpts) { std::vector<char> PredefineBuffer; const char *LineDirective = "# 1 \"<built-in>\" 3\n"; PredefineBuffer.insert(PredefineBuffer.end(), LineDirective, LineDirective+strlen(LineDirective)); // Install things like __POWERPC__, __GNUC__, etc into the macro table. InitializePredefinedMacros(PP.getTargetInfo(), PP.getLangOptions(), PredefineBuffer); // Add on the predefines from the driver. Wrap in a #line directive to report // that they come from the command line. LineDirective = "# 1 \"<command line>\" 1\n"; PredefineBuffer.insert(PredefineBuffer.end(), LineDirective, LineDirective+strlen(LineDirective)); // Process #define's and #undef's in the order they are given. for (PreprocessorInitOptions::macro_iterator I = InitOpts.macro_begin(), E = InitOpts.macro_end(); I != E; ++I) { if (I->second) // isUndef UndefineBuiltinMacro(PredefineBuffer, I->first.c_str()); else DefineBuiltinMacro(PredefineBuffer, I->first.c_str()); } // If -imacros are specified, include them now. These are processed before // any -include directives. for (PreprocessorInitOptions::imacro_iterator I = InitOpts.imacro_begin(), E = InitOpts.imacro_end(); I != E; ++I) AddImplicitIncludeMacros(PredefineBuffer, *I); // Process -include directives. for (PreprocessorInitOptions::include_iterator I = InitOpts.include_begin(), E = InitOpts.include_end(); I != E; ++I) { if (I->second) // isPTH AddImplicitIncludePTH(PredefineBuffer, PP, I->first); else AddImplicitInclude(PredefineBuffer, I->first); } // Null terminate PredefinedBuffer and add it. PredefineBuffer.push_back(0); PP.setPredefines(&PredefineBuffer[0]); // Once we've read this, we're done. return false; }
void NumericLiteralParser::checkSeparator(SourceLocation TokLoc, const char *Pos, CheckSeparatorKind IsAfterDigits) { if (IsAfterDigits == CSK_AfterDigits) { if (Pos == ThisTokBegin) return; --Pos; } else if (Pos == ThisTokEnd) return; if (isDigitSeparator(*Pos)) PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin), diag::err_digit_separator_not_between_digits) << IsAfterDigits; }
void PragmaNamespace::HandlePragma(Preprocessor &PP, Token &Tok) { // Read the 'namespace' that the directive is in, e.g. STDC. Do not macro // expand it, the user can have a STDC #define, that should not affect this. PP.LexUnexpandedToken(Tok); // Get the handler for this token. If there is no handler, ignore the pragma. PragmaHandler *Handler = FindHandler(Tok.getIdentifierInfo(), false); if (Handler == 0) { PP.Diag(Tok, diag::warn_pragma_ignored); return; } // Otherwise, pass it down. Handler->HandlePragma(PP, Tok); }
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind, CodeCompleteConsumer *CodeCompleter) : TheTargetAttributesSema(0), ExternalSource(0), isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()), LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), CollectStats(false), CodeCompleter(CodeCompleter), CurContext(0), OriginalLexicalContext(0), PackContext(0), MSStructPragmaOn(false), VisContext(0), IsBuildingRecoveryCallExpr(false), ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0), IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0), NSNumberDecl(0), NSStringDecl(0), StringWithUTF8StringMethod(0), NSArrayDecl(0), ArrayWithObjectsMethod(0), NSDictionaryDecl(0), DictionaryWithObjectsMethod(0), GlobalNewDeleteDeclared(false), TUKind(TUKind), NumSFINAEErrors(0), IsTransformingLambdaCallOperatorProtoType(false), InFunctionDeclarator(0), AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1), CurrentInstantiationScope(0), TyposCorrected(0), AnalysisWarnings(*this) { TUScope = 0; LoadedExternalKnownNamespaces = false; for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I) NSNumberLiteralMethods[I] = 0; if (getLangOpts().ObjC1) NSAPIObj.reset(new NSAPI(Context)); if (getLangOpts().CPlusPlus) FieldCollector.reset(new CXXFieldCollector()); // Tell diagnostics how to render things from the AST library. PP.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context); ExprEvalContexts.push_back( ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0, false, 0, false)); FunctionScopes.push_back(new FunctionScopeInfo(Diags)); }
/// HasFeature - Return true if we recognize and implement the specified feature /// specified by the identifier. static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { const LangOptions &LangOpts = PP.getLangOptions(); return llvm::StringSwitch<bool>(II->getName()) .Case("blocks", LangOpts.Blocks) .Case("cxx_rtti", LangOpts.RTTI) //.Case("cxx_lambdas", false) //.Case("cxx_nullptr", false) //.Case("cxx_concepts", false) .Case("cxx_decltype", LangOpts.CPlusPlus0x) .Case("cxx_auto_type", LangOpts.CPlusPlus0x) .Case("cxx_exceptions", LangOpts.Exceptions) .Case("cxx_attributes", LangOpts.CPlusPlus0x) .Case("cxx_static_assert", LangOpts.CPlusPlus0x) .Case("objc_nonfragile_abi", LangOpts.ObjCNonFragileABI) .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x) //.Case("cxx_rvalue_references", false) .Case("attribute_overloadable", true) //.Case("cxx_variadic_templates", false) .Case("attribute_ext_vector_type", true) .Case("attribute_analyzer_noreturn", true) .Case("attribute_cf_returns_not_retained", true) .Case("attribute_cf_returns_retained", true) .Case("attribute_ns_returns_not_retained", true) .Case("attribute_ns_returns_retained", true) .Default(false); }
/// Initializes an InclusionRewriter with a \p PP source and \p OS destination. InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers, bool UseLineDirectives) : PP(PP), SM(PP.getSourceManager()), OS(OS), MainEOL("\n"), PredefinesBuffer(nullptr), ShowLineMarkers(ShowLineMarkers), UseLineDirectives(UseLineDirectives), LastInclusionLocation(SourceLocation()) {}
void ento::createPlistMultiFileDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C, const std::string &s, const Preprocessor &PP) { C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP.getLangOpts(), true)); }
void ClassifyImage(Preprocessor &preprocessor, ChessClassifier &classifier, string imageFile, bool showWindow = true, bool showBinarization = false) { IplImage* image = cvLoadImage(imageFile.c_str()); if(showWindow) { cvNamedWindow("Orignal", CV_WINDOW_AUTOSIZE); cvShowImage("Orignal", image); } std::vector<IplImage*>* result = preprocessor.ExtractChess(image); if(showBinarization) { cvNamedWindow("Image1", CV_WINDOW_AUTOSIZE); cvNamedWindow("Image2", CV_WINDOW_AUTOSIZE); cvShowImage("Image1", result->at(0)); cvShowImage("Image2", result->at(1)); } string label1 = classifier.classify(result->at(0)); string label2 = classifier.classify(result->at(1)); std::cout << "Classify Results: " << label1 << " vs " << label2 << endl; if(showWindow || showBinarization) cvWaitKey(0); cvReleaseImage(&result->at(0)); cvReleaseImage(&result->at(1)); result->clear(); cvReleaseImage(&image); if(showWindow || showBinarization) cvDestroyAllWindows(); }
/// isTrivialSingleTokenExpansion - Return true if MI, which has a single token /// in its expansion, currently expands to that token literally. static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, const IdentifierInfo *MacroIdent, Preprocessor &PP) { IdentifierInfo *II = MI->getReplacementToken(0).getIdentifierInfo(); // If the token isn't an identifier, it's always literally expanded. if (II == 0) return true; // If the identifier is a macro, and if that macro is enabled, it may be // expanded so it's not a trivial expansion. if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() && // Fast expanding "#define X X" is ok, because X would be disabled. II != MacroIdent) return false; // If this is an object-like macro invocation, it is safe to trivially expand // it. if (MI->isObjectLike()) return true; // If this is a function-like macro invocation, it's safe to trivially expand // as long as the identifier is not a macro argument. for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end(); I != E; ++I) if (*I == II) return false; // Identifier is a macro argument. return true; }
void OMPPragmaHandler::LexUntil(Preprocessor &PP, Token &Tok, TokenKind Kind) { while (Tok.isNot(Kind) && Tok.isNot(clang::tok::eod)) { PP.Lex(Tok); } }
/// \brief Computes the source location just past the end of the token at /// the given source location. If the location points at a macro, the whole /// macro expansion is skipped. SourceLocation TransformActionsImpl::getLocForEndOfToken(SourceLocation loc, SourceManager &SM, Preprocessor &PP) { if (loc.isMacroID()) loc = SM.getExpansionRange(loc).second; return PP.getLocForEndOfToken(loc); }
/// HandleComment - Hook into the preprocessor and extract comments containing /// expected errors and warnings. bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP, SourceRange Comment) { SourceManager &SM = PP.getSourceManager(); SourceLocation CommentBegin = Comment.getBegin(); const char *CommentRaw = SM.getCharacterData(CommentBegin); StringRef C(CommentRaw, SM.getCharacterData(Comment.getEnd()) - CommentRaw); if (C.empty()) return false; // Fold any "\<EOL>" sequences size_t loc = C.find('\\'); if (loc == StringRef::npos) { ParseDirective(C, &ED, SM, CommentBegin, PP.getDiagnostics(), Status); return false; } std::string C2; C2.reserve(C.size()); for (size_t last = 0;; loc = C.find('\\', last)) { if (loc == StringRef::npos || loc == C.size()) { C2 += C.substr(last); break; } C2 += C.substr(last, loc-last); last = loc + 1; if (C[last] == '\n' || C[last] == '\r') { ++last; // Escape \r\n or \n\r, but not \n\n. if (last < C.size()) if (C[last] == '\n' || C[last] == '\r') if (C[last] != C[last-1]) ++last; } else { // This was just a normal backslash. C2 += '\\'; } } if (!C2.empty()) ParseDirective(C2, &ED, SM, CommentBegin, PP.getDiagnostics(), Status); return false; }
static bool EnableCodeCompletion(Preprocessor &PP, const std::string &Filename, unsigned Line, unsigned Column) { // Tell the source manager to chop off the given file at a specific // line and column. const FileEntry *Entry = PP.getFileManager().getFile(Filename); if (!Entry) { PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) << Filename; return true; } // Truncate the named file at the given line/column. PP.SetCodeCompletionPoint(Entry, Line, Column); return false; }
void clang::AttachDependencyFileGen(Preprocessor &PP, const DependencyOutputOptions &Opts) { if (Opts.Targets.empty()) { PP.getDiagnostics().Report(diag::err_fe_dependency_file_requires_MT); return; } std::string Err; llvm::raw_ostream *OS(new llvm::raw_fd_ostream(Opts.OutputFile.c_str(), Err)); if (!Err.empty()) { PP.getDiagnostics().Report(diag::err_fe_error_opening) << Opts.OutputFile << Err; return; } PP.addPPCallbacks(new DependencyFileCallback(&PP, OS, Opts)); }
bool OMPPragmaHandler::handleList(Token &Tok, Preprocessor &PP, PragmaClause &C) { if (!Tok.is(clang::tok::l_paren)) return false; PP.Lex(Tok); if (C.Type == ReductionClause) { C.Op = Tok; PP.Lex(Tok); if (Tok.isNot(clang::tok::colon)) return false; PP.Lex(Tok); } else if (C.Type == IfClause || C.Type == NumThreadsClause || C.Type == DefaultClause || C.Type == ScheduleClause) { LexUntil(PP, Tok, clang::tok::r_paren); return Tok.is(clang::tok::r_paren); } while(Tok.isNot(clang::tok::eod)) { if (! (Tok.is(clang::tok::identifier))) return false; C.Options.push_back(Tok.getIdentifierInfo()); PP.Lex(Tok); if (Tok.is(clang::tok::r_paren)) { break; } if (Tok.isNot(clang::tok::comma)) return false; PP.Lex(Tok); } if (Tok.is(clang::tok::eod)) { return false; } return true; }
SourceRange OMPPragmaHandler::getTokenRange(Token &Tok, Preprocessor &PP) { SourceLocation Start = Tok.getLocation(); SourceLocation End = PP.getLocForEndOfToken(Start); return SourceRange(Start, End); }
/// EvaluateHasIncludeNext - Process '__has_include_next("path")' expression. /// Returns true if successful. static bool EvaluateHasIncludeNext(Token &Tok, IdentifierInfo *II, Preprocessor &PP) { // __has_include_next is like __has_include, except that we start // searching after the current found directory. If we can't do this, // issue a diagnostic. const DirectoryLookup *Lookup = PP.GetCurDirLookup(); if (PP.isInPrimaryFile()) { Lookup = 0; PP.Diag(Tok, diag::pp_include_next_in_primary); } else if (Lookup == 0) { PP.Diag(Tok, diag::pp_include_next_absolute_path); } else { // Start looking up in the next directory. ++Lookup; } return EvaluateHasIncludeCommon(Tok, II, PP, Lookup); }
Mat extract(const Mat & a) const { Mat feat1; ext->extract(pre.process(a), feat1); if (feat1.type() != CV_32F) feat1.convertTo(feat1,CV_32F); return feat1.reshape(1,1); }
/// CheckResults - This compares the expected results to those that /// were actually reported. It emits any discrepencies. Return "true" if there /// were problems. Return "false" otherwise. /// static bool CheckResults(Preprocessor &PP, const DiagList &ExpectedErrors, const DiagList &ExpectedWarnings, const DiagList &ExpectedNotes) { const DiagnosticClient *DiagClient = PP.getDiagnostics().getClient(); assert(DiagClient != 0 && "DiagChecker requires a valid TextDiagnosticBuffer"); const TextDiagnosticBuffer &Diags = static_cast<const TextDiagnosticBuffer&>(*DiagClient); SourceManager &SourceMgr = PP.getSourceManager(); // We want to capture the delta between what was expected and what was // seen. // // Expected \ Seen - set expected but not seen // Seen \ Expected - set seen but not expected bool HadProblem = false; // See if there are error mismatches. HadProblem |= CompareDiagLists(SourceMgr, ExpectedErrors.begin(), ExpectedErrors.end(), Diags.err_begin(), Diags.err_end(), "Errors expected but not seen:", "Errors seen but not expected:"); // See if there are warning mismatches. HadProblem |= CompareDiagLists(SourceMgr, ExpectedWarnings.begin(), ExpectedWarnings.end(), Diags.warn_begin(), Diags.warn_end(), "Warnings expected but not seen:", "Warnings seen but not expected:"); // See if there are note mismatches. HadProblem |= CompareDiagLists(SourceMgr, ExpectedNotes.begin(), ExpectedNotes.end(), Diags.note_begin(), Diags.note_end(), "Notes expected but not seen:", "Notes seen but not expected:"); return HadProblem; }
/// MayBeDesignationStart - Return true if this token might be the start of a /// designator. If we can tell it is impossible that it is a designator, return /// false. static bool MayBeDesignationStart(tok::TokenKind K, Preprocessor &PP) { switch (K) { default: return false; case tok::period: // designator: '.' identifier case tok::l_square: // designator: array-designator return true; case tok::identifier: // designation: identifier ':' return PP.LookAhead(0).is(tok::colon); } }
void PragmaFPContractHandler::HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) { tok::OnOffSwitch OOS; if (PP.LexOnOffSwitch(OOS)) return; Actions.ActOnPragmaFPContract(OOS); }
/// EvaluateDefined - Process a 'defined(sym)' expression. static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP) { IdentifierInfo *II; Result.setBegin(PeekTok.getLocation()); // Get the next token, don't expand it. PP.LexUnexpandedToken(PeekTok); // Two options, it can either be a pp-identifier or a (. SourceLocation LParenLoc; if (PeekTok.is(tok::l_paren)) { // Found a paren, remember we saw it and skip it. LParenLoc = PeekTok.getLocation(); PP.LexUnexpandedToken(PeekTok); } // If we don't have a pp-identifier now, this is an error. if ((II = PeekTok.getIdentifierInfo()) == 0) { PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier); return true; } // Otherwise, we got an identifier, is it defined to something? Result.Val = II->hasMacroDefinition(); Result.Val.setIsUnsigned(false); // Result is signed intmax_t. // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) { MacroInfo *Macro = PP.getMacroInfo(II); Macro->setIsUsed(true); } // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); // If we are in parens, ensure we have a trailing ). if (LParenLoc.isValid()) { if (PeekTok.isNot(tok::r_paren)) { PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined"; PP.Diag(LParenLoc, diag::note_matching) << "("; return true; } // Consume the ). Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } // Success, remember that we saw defined(X). DT.State = DefinedTracker::DefinedMacro; DT.TheMacro = II; return false; }
/// isIdenticalTo - Return true if the specified macro definition is equal to /// this macro in spelling, arguments, and whitespace. This is used to emit /// duplicate definition warnings. This implements the rules in C99 6.10.3. /// bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const { // Check # tokens in replacement, number of args, and various flags all match. if (ReplacementTokens.size() != Other.ReplacementTokens.size() || getNumArgs() != Other.getNumArgs() || isFunctionLike() != Other.isFunctionLike() || isC99Varargs() != Other.isC99Varargs() || isGNUVarargs() != Other.isGNUVarargs()) return false; // Check arguments. for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end(); I != E; ++I, ++OI) if (*I != *OI) return false; // Check all the tokens. for (unsigned i = 0, e = ReplacementTokens.size(); i != e; ++i) { const Token &A = ReplacementTokens[i]; const Token &B = Other.ReplacementTokens[i]; if (A.getKind() != B.getKind()) return false; // If this isn't the first first token, check that the whitespace and // start-of-line characteristics match. if (i != 0 && (A.isAtStartOfLine() != B.isAtStartOfLine() || A.hasLeadingSpace() != B.hasLeadingSpace())) return false; // If this is an identifier, it is easy. if (A.getIdentifierInfo() || B.getIdentifierInfo()) { if (A.getIdentifierInfo() != B.getIdentifierInfo()) return false; continue; } // Otherwise, check the spelling. if (PP.getSpelling(A) != PP.getSpelling(B)) return false; } return true; }
int Tester::test(string name, bool withoutTokens) { try { Parser parser; Preprocessor preproc; preproc.setIncludeDirectory(""); vector<Token*> tokens = parser.parse(preproc.preprocess(name + ".cmm", "", "../the_best_compilator_ever/cmmlibs/")); std::ofstream log; log.open ("../the_best_compilator_ever/tester/log.txt", std::ios_base::app); log << "======TESTING::" + name + "\n\n---TOKENS:"; string output = CodeGenerator::generate(tokens); if (withoutTokens){ log << "KEY : WithoutTokens\nOutput is "; log << (output != "" ? "not " : "") << "empty\n"; } else { log << output << '\n'; } if (output != "") { fileFromString(name + ".asm", output); log << "-----EXECUTION\n"; string yasm = exec("yasm -felf64 -dgwarf2 "+ name + ".asm -o "+ name + ".o"); log << (yasm == "" ? "YASM OK" : "YASM FAILED") << "\n"; string gcc = (exec("gcc "+ name + ".o -o " + name)); log << (gcc == "" ? "GCC OK" : "GCC FAILED") << "\n"; log << "Execution is finished\n"; } else { std::cout << "\n------Parser output is empty, " + name + "\n"; return 1; } } catch (ParsingException& ignored) { std::cout << "\n------Exception " + std::string(ignored.what()) + "\n"; return 1; } return 0; }