void PreprocessorCallback::Defined(const clang::Token& MacroNameTok, MyMacroDefinition MD,
                                   clang::SourceRange Range)
{
    clang::SourceLocation loc = MacroNameTok.getLocation();
    if (!loc.isValid() || !loc.isFileID())
        return;

    clang::SourceManager &sm = annotator.getSourceMgr();

    clang::FileID FID = sm.getFileID(loc);
    if (!annotator.shouldProcess(FID))
        return;

    std::string ref = llvm::Twine("_M/", MacroNameTok.getIdentifierInfo()->getName()).str();
    std::string link;
    std::string dataProj;
    clang::SourceLocation defLoc;
    clang::FileID defFID;

    if (MD) {
#if CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR >= 7
        auto *MI = MD.getMacroInfo();
#else
        auto *MI = MD->getMacroInfo();
#endif
        if (MI) {
            defLoc = MI->getDefinitionLoc();
            defFID = sm.getFileID(defLoc);
        }
    }

    if (defFID.isInvalid() || defFID != FID) {
        if (!defFID.isInvalid()) {
            link = annotator.pathTo(FID, defFID, &dataProj);
        }
        if (link.empty()) {
            std::string tag = "class=\"macro\" data-ref=\"" % ref % "\"";
            annotator.generator(FID).addTag("span", tag, sm.getFileOffset(loc), MacroNameTok.getLength());
            return;
        }

        if (!dataProj.empty()) {
            dataProj = " data-proj=\"" % dataProj % "\"";
        }
    }

    if (sm.getMainFileID() != defFID) {
        annotator.registerMacro(ref, MacroNameTok.getLocation(), Annotator::Use_Address);
    }

    std::string tag = "class=\"macro\" href=\"" % link % "#" % llvm::Twine(sm.getExpansionLineNumber(defLoc)).str()
        % "\" data-ref=\"" % ref % "\"" % dataProj;
    annotator.generator(FID).addTag("a", tag, sm.getFileOffset(loc), MacroNameTok.getLength());
}
void PragmaRecorder::HandlePragma(clang::Preprocessor &PP,
                                  clang::PragmaIntroducerKind Introducer,
                                  clang::Token &FirstToken) {
  clang::Token &CurrentToken = FirstToken;
  std::string PragmaName, PragmaValue = "";
  // Pragma in ACC should be a name/value pair

  if (GetPragmaNameFromToken(FirstToken, PragmaName)) {
    // start parsing the value '(' PragmaValue ')', if we have one.
    const clang::Token* NextToken = &PP.LookAhead(0);

    if (NextToken->is(clang::tok::l_paren))
      PP.LexUnexpandedToken(CurrentToken);
    else
      goto end_parsing_pragma_value;

    NextToken = &PP.LookAhead(0);
    if (GetPragmaValueFromToken(*NextToken, PragmaValue)) {
      PP.Lex(CurrentToken);
    } else {
      PP.LexUnexpandedToken(CurrentToken);
      PP.Diag(NextToken->getLocation(),
              PP.getDiagnostics().getCustomDiagID(
                  clang::DiagnosticsEngine::Error,
                  "expected value after '#pragma %0('")) << PragmaName;
      return;
    }

    if (!NextToken->is(clang::tok::r_paren)) {
      NextToken = &PP.LookAhead(0);
      if (NextToken->is(clang::tok::r_paren)) {
        PP.LexUnexpandedToken(CurrentToken);
      } else {
        PP.LexUnexpandedToken(CurrentToken);
        PP.Diag(NextToken->getLocation(),
                PP.getDiagnostics().getCustomDiagID(
                    clang::DiagnosticsEngine::Error,
                    "missing ')' after '#pragma %0(%1'"))
            << PragmaName << PragmaValue;
        return;
      }
    }
  } else {
    PP.Diag(FirstToken.getLocation(),
            PP.getDiagnostics().getCustomDiagID(
                clang::DiagnosticsEngine::Error,
                "no pragma name or value"));
    return;
  }

 end_parsing_pragma_value:

  // PragmaValue may be an empty string.
  mPragmas->push_back(make_pair(PragmaName, PragmaValue));

  // Inform lex to eat the token
  PP.LexUnexpandedToken(CurrentToken);

  return;
}
void PreprocessorCallback::MacroDefined(const clang::Token& MacroNameTok, const clang::MacroDirective *MD)
{
    clang::SourceLocation loc = MacroNameTok.getLocation();
    if (!loc.isValid() || !loc.isFileID())
        return;

    clang::SourceManager &sm = annotator.getSourceMgr();
    clang::FileID FID = sm.getFileID(loc);
    if (!annotator.shouldProcess(FID))
        return;

    std::string ref = llvm::Twine("_M/", MacroNameTok.getIdentifierInfo()->getName()).str();

    if (sm.getMainFileID() != FID) {
        annotator.registerMacro(ref, MacroNameTok.getLocation(), Annotator::Declaration);
    }

    annotator.generator(FID).addTag("dfn", "class=\"macro\" id=\""% ref %"\" data-ref=\"" % ref % "\"", sm.getFileOffset(loc), MacroNameTok.getLength());
}
Beispiel #4
0
static best_guess num_type(clang::Preprocessor &pp,
                           const clang::Token &t) {
    llvm::StringRef sr(t.getLiteralData(), t.getLength());
    clang::NumericLiteralParser parser(sr, t.getLocation(), pp);

    if(parser.isIntegerLiteral())
        return tok_int;
    if(parser.isFloatingLiteral())
        return tok_float;

    return tok_invalid;
}
	void FMacroCallback::MacroDefined(const clang::Token &MacroNameTok, const clang::MacroDirective *MD)
	{
		auto MacroName = MacroNameTok.getIdentifierInfo()->getName();

		if (IsMacroDefinedInCommandLine(MacroName) || IsBuiltInMacro(MD) || IsPredefinedMacro(MacroName))
		{
			return;
		}

		auto MacroDefinitionFile = FString(SourceManager.getFilename(MacroNameTok.getLocation()).data());
		MacroDefinitionFile.ReplaceInline(TEXT("\\"), TEXT("/"));
		if (MacroDefinitionFile.IsEmpty())
		{
			OutputFileContents.Logf(TEXT("Found unexpected definition of macro %s."), ANSI_TO_TCHAR(MacroName.data()));
		}
		MacroDefinitionToFile.Add(MacroName.data(), MacroDefinitionFile);
	}
void PreprocessorCallback::MacroExpands(const clang::Token& MacroNameTok,
                                        const clang::MacroInfo* MI,
                                        clang::SourceRange Range)
{
    if (disabled)
        return;

    clang::SourceLocation loc = MacroNameTok.getLocation();
    if (!loc.isValid() || !loc.isFileID())
        return;
    clang::SourceManager &sm = annotator.getSourceMgr();
    clang::FileID FID = sm.getFileID(loc);
    if (!annotator.shouldProcess(FID))
        return;

    const char *begin = sm.getCharacterData(Range.getBegin());
    int len = sm.getCharacterData(Range.getEnd()) - begin;
    len += clang::Lexer::MeasureTokenLength(Range.getEnd(), sm, PP.getLangOpts());

    std::string copy(begin, len);
    begin = copy.c_str();
    clang::Lexer lex(loc, PP.getLangOpts(), begin, begin, begin + len);
    std::vector<clang::Token> tokens;
    std::string expansion;

    //Lousely based on code from clang::html::HighlightMacros

    // Lex all the tokens in raw mode, to avoid entering #includes or expanding
    // macros.
    clang::Token tok;
    do {
        lex.LexFromRawLexer(tok);

        // If this is a # at the start of a line, discard it from the token stream.
        // We don't want the re-preprocess step to see #defines, #includes or other
        // preprocessor directives.
        if (tok.is(clang::tok::hash) && tok.isAtStartOfLine())
            continue;

        // If this is a ## token, change its kind to unknown so that repreprocessing
        // it will not produce an error.
        if (tok.is(clang::tok::hashhash))
            tok.setKind(clang::tok::unknown);

        // If this raw token is an identifier, the raw lexer won't have looked up
        // the corresponding identifier info for it.  Do this now so that it will be
        // macro expanded when we re-preprocess it.
        if (tok.is(clang::tok::raw_identifier))
            PP.LookUpIdentifierInfo(tok);

        tokens.push_back(tok);

    } while(!tok.is(clang::tok::eof));

    // Temporarily change the diagnostics object so that we ignore any generated
    // diagnostics from this pass.
    clang::DiagnosticsEngine TmpDiags(PP.getDiagnostics().getDiagnosticIDs(),
#if CLANG_VERSION_MAJOR!=3 || CLANG_VERSION_MINOR>=2
                                      &PP.getDiagnostics().getDiagnosticOptions(),
#endif
                                      new clang::IgnoringDiagConsumer);

    disabled = true;
    clang::DiagnosticsEngine *OldDiags = &PP.getDiagnostics();
    PP.setDiagnostics(TmpDiags);

    PP.EnterTokenStream(tokens.data(), tokens.size(), false, false);

    PP.Lex(tok);
    while(tok.isNot(clang::tok::eof)) {
        // If the tokens were already space separated, or if they must be to avoid
        // them being implicitly pasted, add a space between them.
        if (tok.hasLeadingSpace())
            expansion += ' ';
           // ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok)) //FIXME
        // Escape any special characters in the token text.
        expansion += PP.getSpelling(tok);
        PP.Lex(tok);
    }

    PP.setDiagnostics(*OldDiags);
    disabled = false;

    expansion = Generator::escapeAttr(expansion);

    clang::SourceLocation defLoc = MI->getDefinitionLoc();
    clang::FileID defFID = sm.getFileID(defLoc);
    std::string link;
    if (defFID != FID)
        link = annotator.pathTo(FID, defFID);
    std::string tag = "class=\"macro\" href=\"" % link % "#" % llvm::Twine(sm.getExpansionLineNumber(defLoc)).str()
                    % "\" title=\"" % expansion % "\"";
    annotator.generator(FID).addTag("a", tag, sm.getFileOffset(loc), MacroNameTok.getLength());
}
Beispiel #7
0
static clang::SourceLocation GetFromLiteral(clang::Token Tok, clang::StringLiteral *Lit, clang::Preprocessor &PP) {
    return Lit->getLocationOfByte(PP.getSourceManager().getFileOffset(Tok.getLocation()),
                           PP.getSourceManager(), PP.getLangOpts(), PP.getTargetInfo());
}