public void testObjectMacroExpansionNested() throws Exception {
    StringBuffer buffer = new StringBuffer("#define XYZ const\n"); // $NON-NLS-1$
    buffer.append("#define PO *\n"); // $NON-NLS-1$
    buffer.append("#define C_PO PO XYZ\n"); // $NON-NLS-1$
    buffer.append("int C_PO var;"); // $NON-NLS-1$
    String code = buffer.toString();

    for (ParserLanguage language : languages) {
      IASTTranslationUnit tu = parse(code, language);
      final IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions();
      IASTPreprocessorMacroDefinition XYZ = macroDefinitions[0];
      IASTPreprocessorMacroDefinition PO = macroDefinitions[1];
      IASTPreprocessorMacroDefinition C_PO = macroDefinitions[2];
      IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
      assertTrue(var.getDeclarators()[0].getPointerOperators().length > 0);
      IASTNodeLocation[] locations = var.getNodeLocations();
      assertEquals(3, locations.length);
      IASTFileLocation start_loc = (IASTFileLocation) locations[0];
      assertEquals(start_loc.getNodeOffset(), code.indexOf("int")); // $NON-NLS-1$
      assertEquals(start_loc.getNodeLength(), "int ".length()); // $NON-NLS-1$
      IASTMacroExpansionLocation mac_loc = (IASTMacroExpansionLocation) locations[1];
      final IASTPreprocessorMacroDefinition C_PO2 = mac_loc.getExpansion().getMacroDefinition();
      assertEqualsMacros(C_PO, C_PO2);
      assertEquals(0, mac_loc.getNodeOffset());
      assertEquals(2, mac_loc.getNodeLength());
      IASTFileLocation end_loc = (IASTFileLocation) locations[2];
      assertEquals(code.indexOf(" var"), end_loc.getNodeOffset()); // $NON-NLS-1$
      assertEquals(" var;".length(), end_loc.getNodeLength()); // $NON-NLS-1$
    }
  }
  private void visitIf(IASTIfStatement statement) throws BadLocationException {
    /* TODO: specific params: don't show the if hint if there's an "else if" after it (by checking if the elseClause is an instance of ifstatment) */

    String hint = ""; // $NON-NLS-1$
    if (statement.getConditionExpression() != null) {
      hint = statement.getConditionExpression().getRawSignature();
    } else {
      if ((statement instanceof ICPPASTIfStatement)
          && ((ICPPASTIfStatement) statement).getConditionDeclaration() != null) {
        hint = ((ICPPASTIfStatement) statement).getConditionDeclaration().getRawSignature();
      }
    }

    IASTStatement thenClause = statement.getThenClause();
    IASTStatement elseClause = statement.getElseClause();

    boolean showIfHint = (elseClause == null);
    int endLoc = -1;
    if (!showIfHint) {
      if (elseClause.getFileLocation().getStartingLineNumber()
          != thenClause.getFileLocation().getEndingLineNumber()) {
        showIfHint = true;
      }

      // if the else looks like this "} else {", then show the hint on the "{"
      if (!showIfHint && !(elseClause instanceof IASTIfStatement)) {
        endLoc = elseClause.getFileLocation().getNodeOffset();
        showIfHint = true;
      }
    }

    if (showIfHint && !(thenClause instanceof IASTCompoundStatement)) showIfHint = false;

    if (showIfHint) {
      IASTFileLocation location = thenClause.getFileLocation();
      if (endLoc == -1) endLoc = location.getNodeOffset() + location.getNodeLength() - 1;
      int startLoc = statement.getFileLocation().getNodeOffset();
      _container.add(
          new Hint(
              "if",
              startLoc,
              endLoc,
              "if( " + hint + " )")); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    }

    if (elseClause != null
        && !(elseClause instanceof IASTIfStatement)
        && (elseClause instanceof IASTCompoundStatement)) {
      IASTFileLocation location = elseClause.getFileLocation();
      endLoc = location.getNodeOffset() + location.getNodeLength() - 1;
      int startLoc = location.getNodeOffset();
      _container.add(
          new Hint(
              "if",
              startLoc,
              endLoc,
              "else_of_if( " + hint + " )")); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    }
  }
    @Override
    public int visit(IASTDeclSpecifier declSpec) {
      if (declSpec instanceof IASTCompositeTypeSpecifier) {
        IASTFileLocation loc = declSpec.getFileLocation();
        if (start > loc.getNodeOffset() && start < loc.getNodeOffset() + loc.getNodeLength()) {
          container.setObject((IASTCompositeTypeSpecifier) declSpec);
          return ASTVisitor.PROCESS_ABORT;
        }
      }

      return super.visit(declSpec);
    }
  private boolean areOverlappingNames(IName n1, IName n2) {
    if (n1 == n2) return true;

    IASTFileLocation loc1 = n1.getFileLocation();
    IASTFileLocation loc2 = n2.getFileLocation();
    if (loc1 == null || loc2 == null) return false;
    return loc1.getFileName().equals(loc2.getFileName())
        && max(loc1.getNodeOffset(), loc2.getNodeOffset())
            < min(
                loc1.getNodeOffset() + loc1.getNodeLength(),
                loc2.getNodeOffset() + loc2.getNodeLength());
  }
 @Override
 public int visit(ICPPASTNamespaceDefinition namespaceDefinition) {
   IASTName name = namespaceDefinition.getName();
   try {
     IASTFileLocation location = namespaceDefinition.getFileLocation();
     int endLoc = location.getNodeOffset() + location.getNodeLength() - 1;
     int startLoc = location.getNodeOffset();
     _container.add(
         new Hint("namespace", startLoc, endLoc, "namespace " + name.toString())); // $NON-NLS-1$
   } catch (BadLocationException e) {
     _cancelProcessing.set(true);
   }
   return shouldContinue();
 }
 public void testObjectMacroExpansionPartialDeclSpec() throws Exception {
   StringBuffer buffer = new StringBuffer("#define XYZ const\n"); // $NON-NLS-1$
   buffer.append("XYZ int var;"); // $NON-NLS-1$
   String code = buffer.toString();
   for (ParserLanguage language : languages) {
     IASTTranslationUnit tu = parse(code, language);
     IASTPreprocessorObjectStyleMacroDefinition defXYZ =
         (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
     IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
     IASTSimpleDeclSpecifier declSpec = (IASTSimpleDeclSpecifier) var.getDeclSpecifier();
     IASTNodeLocation[] declSpecLocations = declSpec.getNodeLocations();
     assertEquals(declSpecLocations.length, 2);
     IASTMacroExpansionLocation expansion = (IASTMacroExpansionLocation) declSpecLocations[0];
     assertEqualsMacros(defXYZ, expansion.getExpansion().getMacroDefinition());
     assertEquals(expansion.getNodeOffset(), 0);
     assertEquals(expansion.getNodeLength(), 1);
     IASTNodeLocation[] expansionLocations = expansion.getExpansion().getNodeLocations();
     assertEquals(expansionLocations.length, 1);
     assertTrue(expansionLocations[0] instanceof IASTFileLocation);
     assertEquals(expansionLocations[0].getNodeOffset(), code.indexOf("XYZ int")); // $NON-NLS-1$
     assertEquals(expansionLocations[0].getNodeLength(), "XYZ".length()); // $NON-NLS-1$
     IASTFileLocation second = (IASTFileLocation) declSpecLocations[1];
     assertEquals(second.getNodeOffset(), code.indexOf(" int")); // $NON-NLS-1$
     assertEquals(second.getNodeLength(), " int".length()); // $NON-NLS-1$
   }
 }
  private PreOccurence createPreOccurence(
      AnalysisConfig config,
      IChecker checker,
      IASTFileLocation fileLocation,
      String msg,
      String declaratorName) {
    final int startLine = fileLocation.getStartingLineNumber();
    final int endLine = fileLocation.getEndingLineNumber();
    final int startOffset = fileLocation.getNodeOffset();
    final int endOffset = startOffset + fileLocation.getNodeLength();

    Map<String, String> tempmap = CppUtil.extractModuleName(translationUnit, startLine);
    String className = tempmap.get("className");
    String methodName = tempmap.get("methodName");

    PreOccurence preOcc = new PreOccurence();
    preOcc.setCheckerCode(checker.getCode());
    preOcc.setFileName(config.getFileName());
    preOcc.setModulePath(config.getModulePath());
    preOcc.setClassName(className);
    preOcc.setMethodName(methodName);
    preOcc.setLanguage(config.getLanguageEnum().toString());
    preOcc.setSeverityCode(checker.getSeverityCode());
    preOcc.setMessage(checker.getDescription());
    preOcc.setToolName(DexterVdCppPlugin.PLUGIN_NAME);
    preOcc.setStartLine(startLine);
    preOcc.setEndLine(endLine);
    preOcc.setCharStart(startOffset);
    preOcc.setCharEnd(endOffset);
    preOcc.setVariableName(declaratorName);
    preOcc.setStringValue(msg);
    preOcc.setMessage(msg);

    return preOcc;
  }
  private void visitFunc(IASTFunctionDefinition declaration) throws BadLocationException {
    IASTStatement body = declaration.getBody();
    if (!(body instanceof IASTCompoundStatement)) return;

    // starting a function empties the stack... (which should already be empty on good flow)
    _scopeStack.clear();

    IASTFileLocation location = body.getFileLocation();
    int endLoc = location.getNodeOffset() + location.getNodeLength() - 1;

    IASTFunctionDeclarator declerator = declaration.getDeclarator();
    int startLoc = declerator.getFileLocation().getNodeOffset();

    StringBuffer hint = new StringBuffer();
    hint.append(declerator.getName().getRawSignature());
    /* TODO: specific params: exclude function parameters (show only the name) */
    hint.append("( "); // $NON-NLS-1$
    IASTNode[] decChildren = declerator.getChildren();
    boolean firstParam = true;
    for (int i = 0; i < decChildren.length; i++) {
      IASTNode node = decChildren[i];
      if (node instanceof IASTParameterDeclaration) {
        IASTParameterDeclaration param = (IASTParameterDeclaration) node;
        if (firstParam) firstParam = false;
        else hint.append(", "); // $NON-NLS-1$
        hint.append(param.getDeclarator().getName());
      }
    }
    hint.append(" )"); // $NON-NLS-1$

    _container.add(new Hint("function", startLoc, endLoc, hint.toString())); // $NON-NLS-1$
  }
  public MultiMacroExpansionExplorer(IASTTranslationUnit tu, IASTFileLocation loc) {
    if (tu == null || loc == null || loc.getNodeLength() == 0) {
      throw new IllegalArgumentException();
    }
    final ILocationResolver resolver = getResolver(tu);
    final IASTNodeSelector nodeLocator = tu.getNodeSelector(null);
    final IASTPreprocessorMacroExpansion[] expansions = resolver.getMacroExpansions(loc);
    final int count = expansions.length;

    loc = extendLocation(loc, expansions);
    fMacroLocations = getMacroLocations(resolver);
    fFilePath = tu.getFilePath();
    fSource = resolver.getUnpreprocessedSignature(loc);
    fBoundaries = new int[count * 2 + 1];
    fDelegates = new SingleMacroExpansionExplorer[count];

    final int firstOffset = loc.getNodeOffset();
    int bidx = -1;
    int didx = -1;
    for (IASTPreprocessorMacroExpansion expansion : expansions) {
      IASTName ref = expansion.getMacroReference();
      if (ref != null) {
        ArrayList<IASTName> refs = new ArrayList<IASTName>();
        refs.add(ref);
        refs.addAll(Arrays.asList(expansion.getNestedMacroReferences()));
        IASTFileLocation refLoc = expansion.getFileLocation();
        int from = refLoc.getNodeOffset() - firstOffset;
        int to = from + refLoc.getNodeLength();
        IASTNode enclosing = nodeLocator.findEnclosingNode(from + firstOffset - 1, 2);
        boolean isPPCond =
            enclosing instanceof IASTPreprocessorIfStatement
                || enclosing instanceof IASTPreprocessorElifStatement;
        fBoundaries[++bidx] = from;
        fBoundaries[++bidx] = to;
        fDelegates[++didx] =
            new SingleMacroExpansionExplorer(
                new String(fSource, from, to - from),
                refs.toArray(new IASTName[refs.size()]),
                fMacroLocations,
                fFilePath,
                refLoc.getStartingLineNumber(),
                isPPCond,
                (LexerOptions) tu.getAdapter(LexerOptions.class));
      }
    }
    fBoundaries[++bidx] = fSource.length;
  }
  private void addBrackets(IASTNode[] args) throws BadLocationException {
    if (args == null || args.length == 0) return;

    int startLoc = args[0].getFileLocation().getNodeOffset() - 1;
    IASTFileLocation endFileLoc = args[args.length - 1].getFileLocation();
    int endLoc = endFileLoc.getNodeOffset() + endFileLoc.getNodeLength();
    _container.add(new BracketsPair(startLoc, '<', endLoc, '>'));
  }
Exemple #11
0
  private void handleReplace(IASTNode node) {
    List<ASTModification> modifications = getModifications(node, ModificationKind.REPLACE);
    String source = node.getTranslationUnit().getRawSignature();
    TextEdit edit;
    ChangeGeneratorWriterVisitor writer =
        new ChangeGeneratorWriterVisitor(modificationStore, commentMap);
    IASTFileLocation fileLocation = node.getFileLocation();
    Integer val = sourceOffsets.get(fileLocation.getFileName());
    int processedOffset = val != null ? val.intValue() : 0;
    if (modifications.size() == 1 && modifications.get(0).getNewNode() == null) {
      int offset = getOffsetIncludingComments(node);
      int endOffset = getEndOffsetIncludingComments(node);
      offset = Math.max(skipPrecedingBlankLines(source, offset), processedOffset);
      endOffset = skipTrailingBlankLines(source, endOffset);
      IASTNode[] siblingsList = getContainingNodeList(node);
      if (siblingsList != null) {
        if (siblingsList.length > 1) {
          if (node == siblingsList[0]) {
            endOffset = skipToTrailingDelimiter(source, ',', endOffset);
          } else {
            offset = skipToPrecedingDelimiter(source, ',', offset);
          }
        } else if (node.getPropertyInParent() == ICPPASTFunctionDefinition.MEMBER_INITIALIZER) {
          offset = skipToPrecedingDelimiter(source, ':', offset);
        }
      }
      IASTNode prevNode = getPreviousSiblingOrPreprocessorNode(node);
      IASTNode nextNode = getNextSiblingOrPreprocessorNode(node);
      if (prevNode != null && nextNode != null) {
        if (ASTWriter.requireBlankLineInBetween(prevNode, nextNode)) {
          writer.newLine();
        }
      } else if (node.getParent() instanceof ICPPASTNamespaceDefinition) {
        writer.newLine();
      }
      String code = writer.toString();
      edit = new ReplaceEdit(offset, endOffset - offset, code);
    } else {
      node.accept(writer);
      String code = writer.toString();
      int offset = fileLocation.getNodeOffset();
      int endOffset = offset + fileLocation.getNodeLength();
      if (node instanceof IASTStatement || node instanceof IASTDeclaration) {
        // Include trailing comments in the area to be replaced.
        endOffset = Math.max(endOffset, getEndOffsetIncludingTrailingComments(node));
      }
      String lineSeparator = writer.getScribe().getLineSeparator();
      if (code.endsWith(lineSeparator)) {
        code = code.substring(0, code.length() - lineSeparator.length());
      }
      edit = new ReplaceEdit(offset, endOffset - offset, code);
    }
    IFile file = FileHelper.getFileFromNode(node);
    MultiTextEdit parentEdit = getEdit(node, file);
    parentEdit.addChild(edit);

    sourceOffsets.put(fileLocation.getFileName(), edit.getExclusiveEnd());
  }
  public void testStdioBug() throws ParserException {
    StringBuffer buffer = new StringBuffer("#define    _PTR        void *\n"); // $NON-NLS-1$
    buffer.append("#define __cdecl __attribute__ ((__cdecl__))\n"); // $NON-NLS-1$
    buffer.append("#define _EXFUN(name, proto)     __cdecl name proto\n"); // $NON-NLS-1$
    buffer.append("_PTR     _EXFUN(memchr,(const _PTR, int, size_t));\n"); // $NON-NLS-1$
    String code = buffer.toString();

    for (ParserLanguage language : languages) {
      IASTTranslationUnit tu = parse(code, language, true, true);
      final IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions();
      IASTPreprocessorObjectStyleMacroDefinition _PTR =
          (IASTPreprocessorObjectStyleMacroDefinition) macroDefinitions[0];
      IASTPreprocessorFunctionStyleMacroDefinition _EXFUN =
          (IASTPreprocessorFunctionStyleMacroDefinition) macroDefinitions[2];
      IASTSimpleDeclaration memchr = (IASTSimpleDeclaration) tu.getDeclarations()[0];
      IASTNodeLocation[] locations = memchr.getNodeLocations();
      assertEquals(locations.length, 4);
      IASTMacroExpansionLocation loc_1 = (IASTMacroExpansionLocation) locations[0];
      assertEqualsMacros(_PTR, loc_1.getExpansion().getMacroDefinition());
      IASTFileLocation loc_2 = (IASTFileLocation) locations[1];
      assertEquals(loc_2.getNodeOffset(), code.indexOf("     _EXFUN(")); // $NON-NLS-1$
      assertEquals(loc_2.getNodeLength(), "     ".length()); // $NON-NLS-1$
      IASTMacroExpansionLocation loc_3 = (IASTMacroExpansionLocation) locations[2];
      assertEqualsMacros(_EXFUN, loc_3.getExpansion().getMacroDefinition());
      IASTFileLocation loc_4 = (IASTFileLocation) locations[3];
      assertEquals(loc_4.getNodeOffset(), code.indexOf(";")); // $NON-NLS-1$
      assertEquals(loc_4.getNodeLength(), 1);
      IASTFileLocation flat = memchr.getFileLocation();
      assertEquals(
          flat.getNodeOffset(),
          code.indexOf("_PTR     _EXFUN(memchr,(const _PTR, int, size_t));")); // $NON-NLS-1$
      assertEquals(
          flat.getNodeLength(),
          "_PTR     _EXFUN(memchr,(const _PTR, int, size_t));".length()); // $NON-NLS-1$

      IASTDeclarator d = memchr.getDeclarators()[0];
      IASTFileLocation f = d.getFileLocation();
      assertEquals(
          code.indexOf("_PTR     _EXFUN(memchr,(const _PTR, int, size_t))"),
          f.getNodeOffset()); // $NON-NLS-1$
      assertEquals(
          "_PTR     _EXFUN(memchr,(const _PTR, int, size_t))".length(),
          f.getNodeLength()); // $NON-NLS-1$
    }
  }
 private void visitSwitch(IASTSwitchStatement statement) throws BadLocationException {
   String hint = statement.getControllerExpression().getRawSignature();
   IASTFileLocation location = statement.getBody().getFileLocation();
   int endLoc = location.getNodeOffset() + location.getNodeLength() - 1;
   int startLoc = statement.getFileLocation().getNodeOffset();
   hint = "switch( " + hint + " )"; // $NON-NLS-1$ //$NON-NLS-2$
   _container.add(new Hint("switch", startLoc, endLoc, hint)); // $NON-NLS-1$
   _scopeStack.push(new ScopeInfo(hint, startLoc, statement));
 }
 /**
  * Compute the end offset of give AST node.
  *
  * @param node
  * @return
  */
 private int getEndOffset(IASTNode node) {
   IASTFileLocation fileLocation = getMaxFileLocation(node.getNodeLocations());
   if (fileLocation != null) {
     return fileLocation.getNodeOffset() + fileLocation.getNodeLength();
   }
   // fallback: use container range end
   DocumentRangeNode container = getCurrentContainer();
   Position containerRange = container.getRange();
   return containerRange.getOffset() + containerRange.getLength();
 }
  private void visitType(IASTSimpleDeclaration declaration) throws BadLocationException {
    /* TODO: specific params: include type('class' / 'struct') */

    IASTDeclSpecifier spec = declaration.getDeclSpecifier();
    if (spec instanceof IASTCompositeTypeSpecifier) {
      String hint = ((IASTCompositeTypeSpecifier) spec).getName().getRawSignature();
      if (hint.isEmpty()) return;

      IASTFileLocation location = declaration.getFileLocation();
      int endLoc = location.getNodeOffset() + location.getNodeLength() - 1;
      int startLoc = location.getNodeOffset();
      _container.add(new Hint("type", startLoc, endLoc, hint)); // $NON-NLS-1$
    }

    if (spec instanceof ICPPASTNamedTypeSpecifier) {
      IASTName name = ((ICPPASTNamedTypeSpecifier) spec).getName();
      addBrackets(name);
    }
  }
 private void assertExpressionLocation(IASTDeclaration decl, int index, int length) {
   IASTSimpleDeclaration var = (IASTSimpleDeclaration) decl;
   IASTEqualsInitializer initializer =
       (IASTEqualsInitializer) var.getDeclarators()[0].getInitializer();
   IASTInitializerClause expr = initializer.getInitializerClause();
   IASTFileLocation fileLocation = expr.getFileLocation();
   assertNotNull(fileLocation);
   assertEquals(index, fileLocation.getNodeOffset());
   assertEquals(length, fileLocation.getNodeLength());
 }
Exemple #17
0
 /**
  * Returns a replace edit whose offset is the position where child appended nodes should be
  * inserted at. The text contains the content of the code region that will be disturbed by the
  * insertion.
  *
  * @param node The node to append children to.
  * @return a ReplaceEdit object, or <code>null</code> if the node does not support appending
  *     children to it.
  */
 private ReplaceEdit getAppendAnchor(IASTNode node) {
   if (!(node instanceof IASTCompositeTypeSpecifier
       || node instanceof IASTCompoundStatement
       || node instanceof ICPPASTNamespaceDefinition)) {
     return null;
   }
   String code = node.getRawSignature();
   IASTFileLocation location = node.getFileLocation();
   int pos = location.getNodeOffset() + location.getNodeLength();
   int len = code.endsWith("}") ? 1 : 0; // $NON-NLS-1$
   int insertPos = code.length() - len;
   int startOfLine = skipPrecedingBlankLines(code, insertPos);
   if (startOfLine == insertPos) {
     // Include the closing brace in the region that will be reformatted.
     return new ReplaceEdit(pos - len, len, code.substring(insertPos));
   }
   return new ReplaceEdit(
       location.getNodeOffset() + startOfLine, insertPos - startOfLine, ""); // $NON-NLS-1$
 }
  private IASTFileLocation extendLocation(
      IASTFileLocation loc, final IASTPreprocessorMacroExpansion[] expansions) {
    final int count = expansions.length;
    if (count > 0) {
      int from = loc.getNodeOffset();
      int to = from + loc.getNodeLength();

      final int lfrom = expansions[0].getFileLocation().getNodeOffset();
      final IASTFileLocation l = expansions[count - 1].getFileLocation();
      final int lto = l.getNodeOffset() + l.getNodeLength();

      if (lfrom < from || lto > to) {
        from = Math.min(from, lfrom);
        to = Math.max(to, lto);
        loc = new ASTFileLocation(loc.getFileName(), from, to - from);
      }
    }
    return loc;
  }
  public void testObjectMacroExpansionComplex() throws Exception {
    StringBuffer buffer = new StringBuffer("#define XYZ const\n"); // $NON-NLS-1$
    buffer.append("#define PO *\n"); // $NON-NLS-1$
    buffer.append("#define C_PO PO XYZ\n"); // $NON-NLS-1$
    buffer.append("#define IT int\n"); // $NON-NLS-1$
    buffer.append("#define V var\n"); // $NON-NLS-1$
    buffer.append("XYZ IT C_PO C_PO V;"); // $NON-NLS-1$
    String code = buffer.toString();

    for (ParserLanguage language : languages) {
      IASTTranslationUnit tu = parse(code, language);
      IASTPreprocessorObjectStyleMacroDefinition XYZ =
          (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
      //            IASTPreprocessorObjectStyleMacroDefinition PO =
      // (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[1];
      IASTPreprocessorObjectStyleMacroDefinition C_PO =
          (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[2];
      IASTPreprocessorObjectStyleMacroDefinition IT =
          (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[3];
      IASTPreprocessorObjectStyleMacroDefinition V =
          (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[4];

      IASTSimpleDeclaration var = (IASTSimpleDeclaration) tu.getDeclarations()[0];
      final IASTNodeLocation[] nodeLocations = var.getNodeLocations();

      assertEquals(10, nodeLocations.length);
      IASTMacroExpansionLocation first_loc = (IASTMacroExpansionLocation) nodeLocations[0];
      assertEqualsMacros(first_loc.getExpansion().getMacroDefinition(), XYZ);
      IASTFileLocation second_loc = (IASTFileLocation) nodeLocations[1];
      assertEquals(1, second_loc.getNodeLength());
      IASTMacroExpansionLocation third_loc = (IASTMacroExpansionLocation) nodeLocations[2];
      assertEqualsMacros(third_loc.getExpansion().getMacroDefinition(), IT);
      IASTFileLocation fourth_loc = (IASTFileLocation) nodeLocations[3];
      assertEquals(1, fourth_loc.getNodeLength());
      IASTMacroExpansionLocation fifth_loc = (IASTMacroExpansionLocation) nodeLocations[4];
      assertEqualsMacros(fifth_loc.getExpansion().getMacroDefinition(), C_PO);
      IASTFileLocation sixth_loc = (IASTFileLocation) nodeLocations[5];
      assertEquals(1, sixth_loc.getNodeLength());
      IASTMacroExpansionLocation seventh_loc = (IASTMacroExpansionLocation) nodeLocations[6];
      assertEqualsMacros(seventh_loc.getExpansion().getMacroDefinition(), C_PO);
      IASTFileLocation eighth_loc = (IASTFileLocation) nodeLocations[7];
      assertEquals(1, eighth_loc.getNodeLength());
      IASTMacroExpansionLocation ninth_loc = (IASTMacroExpansionLocation) nodeLocations[8];
      assertEqualsMacros(ninth_loc.getExpansion().getMacroDefinition(), V);
      IASTFileLocation tenth_loc = (IASTFileLocation) nodeLocations[9];
      assertEquals(1, tenth_loc.getNodeLength());

      final IASTFileLocation flatLocation = var.getFileLocation();
      assertNotNull(flatLocation);
      assertEquals(
          code.indexOf("XYZ IT C_PO C_PO V;"), flatLocation.getNodeOffset()); // $NON-NLS-1$
      assertEquals("XYZ IT C_PO C_PO V;".length(), flatLocation.getNodeLength()); // $NON-NLS-1$
    }
  }
 private void assertMacroLocation(IASTDeclaration decl, int index, int length) {
   IASTSimpleDeclaration var = (IASTSimpleDeclaration) decl;
   IASTEqualsInitializer initializer =
       (IASTEqualsInitializer) var.getDeclarators()[0].getInitializer();
   IASTInitializerClause expr = initializer.getInitializerClause();
   assertNotNull(expr.getFileLocation());
   IASTNodeLocation[] locations = expr.getNodeLocations();
   assertEquals(1, locations.length);
   IASTMacroExpansionLocation macroExpansion = (IASTMacroExpansionLocation) locations[0];
   IASTNodeLocation[] expLocations = macroExpansion.getExpansion().getNodeLocations();
   assertEquals(1, expLocations.length);
   IASTFileLocation fileLocation = expLocations[0].asFileLocation();
   assertEquals(index, fileLocation.getNodeOffset());
   assertEquals(length, fileLocation.getNodeLength());
 }
 /**
  * Compute the start offset of given AST node.
  *
  * @param node
  * @return
  */
 private int getStartOffset(IASTNode node) {
   IASTFileLocation fileLocation = getMinFileLocation(node.getNodeLocations());
   if (fileLocation != null) {
     return fileLocation.getNodeOffset();
   }
   DocumentRangeNode container = getCurrentContainer();
   Object[] children = container.getChildren();
   if (children != null && children.length > 0) {
     Position prevRange = ((DocumentRangeNode) children[children.length - 1]).getRange();
     return prevRange.getOffset() + prevRange.getLength();
   }
   // fallback: use container range start
   Position containerRange = container.getRange();
   return containerRange.getOffset();
 }
  public PDOMMacroReferenceName(
      PDOMLinkage linkage, IASTName name, PDOMFile file, PDOMMacroContainer container)
      throws CoreException {
    this.linkage = linkage;
    Database db = linkage.getDB();
    record = db.malloc(RECORD_SIZE);

    db.putRecPtr(record + CONTAINER_REC_OFFSET, container.getRecord());
    db.putRecPtr(record + FILE_REC_OFFSET, file.getRecord());

    // Record our location in the file
    IASTFileLocation fileloc = name.getFileLocation();
    db.putInt(record + NODE_OFFSET_OFFSET, fileloc.getNodeOffset());
    db.putShort(record + NODE_LENGTH_OFFSET, (short) fileloc.getNodeLength());
    container.addReference(this);
  }
  private void visitWhile(IASTWhileStatement statement) throws BadLocationException {
    IASTExpression cond = statement.getCondition();
    String hint = ""; // $NON-NLS-1$
    if (cond != null) hint = cond.getRawSignature();
    hint = "while( " + hint + " )"; // $NON-NLS-1$ //$NON-NLS-2$
    int startLoc = statement.getFileLocation().getNodeOffset();
    _scopeStack.push(new ScopeInfo(hint, startLoc, statement));

    IASTStatement body = statement.getBody();
    if (body instanceof IASTCompoundStatement) {
      IASTFileLocation location = body.getFileLocation();

      int endLoc = location.getNodeOffset() + location.getNodeLength() - 1;
      _container.add(new Hint("while", startLoc, endLoc, hint)); // $NON-NLS-1$
    }
  }
 private void addLocations(
     IASTPreprocessorMacroDefinition[] defs, final Map<IMacroBinding, IASTFileLocation> result) {
   for (IASTPreprocessorMacroDefinition def : defs) {
     IASTName name = def.getName();
     if (name != null) {
       IASTFileLocation loc = name.getFileLocation();
       if (loc != null) {
         final IBinding binding = name.getBinding();
         if (binding instanceof IMacroBinding) {
           loc = new ASTFileLocation(loc.getFileName(), loc.getNodeOffset(), loc.getNodeLength());
           result.put((IMacroBinding) binding, loc);
         }
       }
     }
   }
 }
  private void visitFor(IASTForStatement statement) throws BadLocationException {
    /* TODO: specific params: show also initializer && increment expressions */

    IASTExpression cond = statement.getConditionExpression();
    String hint = ""; // $NON-NLS-1$
    if (cond != null) hint = cond.getRawSignature();
    hint = "for( " + hint + " )"; // $NON-NLS-1$ //$NON-NLS-2$
    int startLoc = statement.getFileLocation().getNodeOffset();
    _scopeStack.push(new ScopeInfo(hint, startLoc, statement));

    IASTStatement body = statement.getBody();
    if (body instanceof IASTCompoundStatement) {
      IASTFileLocation location = body.getFileLocation();
      int endLoc = location.getNodeOffset() + location.getNodeLength() - 1;
      _container.add(new Hint("for", startLoc, endLoc, hint)); // $NON-NLS-1$
    }
  }
  private boolean navigateToLocation(IASTFileLocation fileloc) {
    if (fileloc == null) {
      return false;
    }
    final IPath path = new Path(fileloc.getFileName());
    final int offset = fileloc.getNodeOffset();
    final int length = fileloc.getNodeLength();

    runInUIThread(
        new Runnable() {
          public void run() {
            try {
              fAction.open(path, offset, length);
            } catch (CoreException e) {
              CUIPlugin.log(e);
            }
          }
        });
    return true;
  }
 private ICElementHandle getCElementForName(ICProject project, IIndex index, IName declName)
     throws CoreException {
   if (declName instanceof IIndexName) {
     return IndexUI.getCElementForName(project, index, (IIndexName) declName);
   }
   if (declName instanceof IASTName) {
     IASTName astName = (IASTName) declName;
     IBinding binding = astName.resolveBinding();
     if (binding != null) {
       ITranslationUnit tu = IndexUI.getTranslationUnit(project, astName);
       if (tu != null) {
         IASTFileLocation loc = astName.getFileLocation();
         IRegion region = new Region(loc.getNodeOffset(), loc.getNodeLength());
         return CElementHandleFactory.create(tu, binding, astName.isDefinition(), region, 0);
       }
     }
     return null;
   }
   return null;
 }
 public int getEndOffsetIncludingComments(IASTNode node) {
   int endOffset = 0;
   while (true) {
     IASTFileLocation fileLocation = node.getFileLocation();
     if (fileLocation != null)
       endOffset =
           Math.max(endOffset, fileLocation.getNodeOffset() + fileLocation.getNodeLength());
     List<IASTComment> comments = trailingMap.get(node);
     if (comments != null && !comments.isEmpty()) {
       for (IASTComment comment : comments) {
         int commentEndOffset = ASTNodes.endOffset(comment);
         if (commentEndOffset >= endOffset) {
           endOffset = commentEndOffset;
         }
       }
     }
     IASTNode[] children = node.getChildren();
     if (children.length == 0) break;
     node = children[children.length - 1];
   }
   return endOffset;
 }
 public void testBug90978() throws Exception {
   StringBuffer buffer = new StringBuffer("#define MACRO mm\n"); // $NON-NLS-1$
   buffer.append("int MACRO;\n"); // $NON-NLS-1$
   String code = buffer.toString();
   for (ParserLanguage language : languages) {
     IASTTranslationUnit tu = parse(code, language);
     IASTPreprocessorObjectStyleMacroDefinition MACRO =
         (IASTPreprocessorObjectStyleMacroDefinition) tu.getMacroDefinitions()[0];
     IASTName macro_name = MACRO.getName();
     IMacroBinding binding = (IMacroBinding) macro_name.resolveBinding();
     IASTName[] references = tu.getReferences(binding);
     assertEquals(references.length, 1);
     IASTName reference = references[0];
     IASTNodeLocation[] nodeLocations = reference.getNodeLocations();
     assertEquals(nodeLocations.length, 1);
     assertTrue(nodeLocations[0] instanceof IASTFileLocation);
     IASTFileLocation loc = (IASTFileLocation) nodeLocations[0];
     assertEquals(
         code.indexOf("int MACRO") + "int ".length(),
         loc.getNodeOffset()); // $NON-NLS-1$ //$NON-NLS-2$
     assertEquals("MACRO".length(), loc.getNodeLength()); // $NON-NLS-1$
   }
 }
 @Override
 public void modifyAST(IIndex index, IMarker marker) {
   CompositeChange c = new CompositeChange(Messages.QuickFixCreateParameter_0);
   try {
     ITranslationUnit baseTU = getTranslationUnitViaEditor(marker);
     IASTTranslationUnit baseAST = baseTU.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
     IASTName astName = getASTNameFromMarker(marker, baseAST);
     if (astName == null) {
       return;
     }
     IASTDeclaration declaration =
         CxxAstUtils.createDeclaration(astName, baseAST.getASTNodeFactory(), index);
     // We'll need a FunctionParameterDeclaration later
     final IASTDeclSpecifier finalDeclSpec = (IASTDeclSpecifier) declaration.getChildren()[0];
     final IASTDeclarator finalDeclarator = (IASTDeclarator) declaration.getChildren()[1];
     IASTFunctionDefinition function = CxxAstUtils.getEnclosingFunction(astName);
     if (function == null) {
       return;
     }
     // Find the function declarations
     NameFinderVisitor nameFinderVisitor = new NameFinderVisitor();
     function.accept(nameFinderVisitor);
     IASTName funcName = nameFinderVisitor.name;
     IBinding binding = funcName.resolveBinding();
     IIndexName[] declarations = index.findNames(binding, IIndex.FIND_DECLARATIONS_DEFINITIONS);
     if (declarations.length == 0) {
       return;
     }
     HashMap<ITranslationUnit, IASTTranslationUnit> cachedASTs =
         new HashMap<ITranslationUnit, IASTTranslationUnit>();
     HashMap<ITranslationUnit, ASTRewrite> cachedRewrites =
         new HashMap<ITranslationUnit, ASTRewrite>();
     for (IIndexName iname : declarations) {
       ITranslationUnit declTU = CxxAstUtils.getTranslationUnitFromIndexName(iname);
       if (declTU == null) {
         continue;
       }
       ASTRewrite rewrite;
       IASTTranslationUnit declAST;
       if (!cachedASTs.containsKey(declTU)) {
         declAST = declTU.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
         rewrite = ASTRewrite.create(declAST);
         cachedASTs.put(declTU, declAST);
         cachedRewrites.put(declTU, rewrite);
       } else {
         declAST = cachedASTs.get(declTU);
         rewrite = cachedRewrites.get(declTU);
       }
       IASTFileLocation fileLocation = iname.getFileLocation();
       IASTName declName =
           declAST
               .getNodeSelector(null)
               .findEnclosingName(fileLocation.getNodeOffset(), fileLocation.getNodeLength());
       if (declName == null) {
         continue;
       }
       INodeFactory factory = declAST.getASTNodeFactory();
       IASTFunctionDeclarator functionDecl;
       {
         IASTNode n = declName;
         while (n instanceof IASTName) {
           n = n.getParent();
         }
         functionDecl = (IASTFunctionDeclarator) n;
       }
       IASTParameterDeclaration newParam =
           factory.newParameterDeclaration(finalDeclSpec, finalDeclarator);
       rewrite.insertBefore(functionDecl, null, newParam, null);
     }
     for (ASTRewrite rewrite : cachedRewrites.values()) {
       c.add(rewrite.rewriteAST());
     }
     c.perform(new NullProgressMonitor());
   } catch (CoreException e) {
     CheckersUiActivator.log(e);
   }
 }