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$
  }
Beispiel #2
0
  public boolean forFriendship() {
    if (astName == null) return false;
    IASTNode node = astName.getParent();
    while (node instanceof IASTName) node = node.getParent();

    IASTDeclaration decl = null;
    IASTDeclarator dtor = null;
    if (node instanceof ICPPASTDeclSpecifier && node.getParent() instanceof IASTDeclaration) {
      decl = (IASTDeclaration) node.getParent();
    } else if (node instanceof IASTDeclarator) {
      dtor = (IASTDeclarator) node;
      while (dtor.getParent() instanceof IASTDeclarator) dtor = (IASTDeclarator) dtor.getParent();
      if (!(dtor.getParent() instanceof IASTDeclaration)) return false;
      decl = (IASTDeclaration) dtor.getParent();
    } else {
      return false;
    }
    if (decl instanceof IASTSimpleDeclaration) {
      IASTSimpleDeclaration simple = (IASTSimpleDeclaration) decl;
      if (!((ICPPASTDeclSpecifier) simple.getDeclSpecifier()).isFriend()) return false;
      if (dtor != null) return true;
      return simple.getDeclarators().length == 0;
    } else if (decl instanceof IASTFunctionDefinition) {
      IASTFunctionDefinition fnDef = (IASTFunctionDefinition) decl;
      if (!((ICPPASTDeclSpecifier) fnDef.getDeclSpecifier()).isFriend()) return false;
      return (dtor != null);
    }
    return false;
  }
  @Override
  protected void collectModifications(IProgressMonitor pm, ModificationCollector collector)
      throws CoreException, OperationCanceledException {
    List<IASTNode> getterAndSetters = new ArrayList<IASTNode>();
    List<IASTFunctionDefinition> definitions = new ArrayList<IASTFunctionDefinition>();
    for (GetterSetterInsertEditProvider currentProvider : context.selectedFunctions) {
      if (context.isDefinitionSeparate()) {
        getterAndSetters.add(currentProvider.getFunctionDeclaration());
        IASTFunctionDefinition functionDefinition = currentProvider.getFunctionDefinition(true);
        // Standalone definitions in a header file have to be declared inline.
        if (definitionInsertLocation.getTranslationUnit().isHeaderUnit()) {
          functionDefinition.getDeclSpecifier().setInline(true);
        }
        definitions.add(functionDefinition);
      } else {
        getterAndSetters.add(currentProvider.getFunctionDefinition(false));
      }
    }
    if (context.isDefinitionSeparate()) {
      addDefinition(collector, definitions, pm);
    }
    ICPPASTCompositeTypeSpecifier classDefinition =
        (ICPPASTCompositeTypeSpecifier)
            context.existingFields.get(context.existingFields.size() - 1).getParent();

    AddDeclarationNodeToClassChange.createChange(
        classDefinition, VisibilityEnum.v_public, getterAndSetters, false, collector);
  }
Beispiel #4
0
  // _MYMACRO_ myType foo();
  // _MYMACRO_ myType foo() {}
  // extern void foo2() _MYMACRO_;
  public void testUndefinedMacrosInFunctionDeclarations_Bug234085() throws Exception {
    final String comment = getAboveComment();
    for (ParserLanguage lang : ParserLanguage.values()) {
      IASTTranslationUnit tu = parse(comment, lang, false, false);
      IASTProblemDeclaration pd = getDeclaration(tu, 0);
      assertEquals("_MYMACRO_", pd.getRawSignature());
      IASTSimpleDeclaration sdecl = getDeclaration(tu, 1);
      assertEquals("myType foo();", sdecl.getRawSignature());

      pd = getDeclaration(tu, 2);
      assertEquals("_MYMACRO_", pd.getRawSignature());
      IASTFunctionDefinition fdef = getDeclaration(tu, 3);
      assertEquals("myType foo() {}", fdef.getRawSignature());

      sdecl = getDeclaration(tu, 4);
      assertEquals("extern void foo2()", sdecl.getRawSignature());
      pd = getDeclaration(tu, 5); // the missing semicolon

      if (lang == ParserLanguage.CPP) {
        pd = getDeclaration(tu, 6);
        assertEquals("_MYMACRO_;", pd.getRawSignature());
      } else {
        sdecl = getDeclaration(tu, 6);
        assertEquals("_MYMACRO_;", sdecl.getRawSignature());
      }
    }
  }
 public void testBug94933() throws Exception {
   StringBuffer buffer = new StringBuffer("#define API extern\n"); // $NON-NLS-1$
   buffer.append("#define MYAPI API\n"); // $NON-NLS-1$
   buffer.append("MYAPI void func() {}"); // $NON-NLS-1$
   String code = buffer.toString();
   for (ParserLanguage language : languages) {
     IASTTranslationUnit tu = parse(code, language);
     IASTFunctionDefinition f = (IASTFunctionDefinition) tu.getDeclarations()[0];
     assertNotNull(f.getFileLocation());
   }
 }
 @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);
   }
 }
 /*
  * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
  */
 @Override
 public int visit(IASTDeclaration node) {
   boolean isTemplateDecl = isTemplateDecl(node);
   final int startOffset =
       isTemplateDecl ? getStartOffset(node.getParent()) : getStartOffset(node);
   final int endOffset = getEndOffset(node);
   if (node instanceof IASTFunctionDefinition) {
     IASTFunctionDefinition functionDef = (IASTFunctionDefinition) node;
     final int nodeType;
     if (inClassBody()) {
       nodeType = isTemplateDecl ? ICElement.C_TEMPLATE_METHOD : ICElement.C_METHOD;
     } else {
       nodeType = isTemplateDecl ? ICElement.C_TEMPLATE_FUNCTION : ICElement.C_FUNCTION;
     }
     push(nodeType, getDeclaratorName(functionDef.getDeclarator()), startOffset);
     pop(endOffset);
     return PROCESS_SKIP;
   } else if (node instanceof IASTSimpleDeclaration) {
     IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) node;
     IASTDeclSpecifier declSpec = simpleDecl.getDeclSpecifier();
     if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
       ICPPASTCompositeTypeSpecifier compositeTypeSpec = (ICPPASTCompositeTypeSpecifier) declSpec;
       final String nodeName = getTypeName(compositeTypeSpec);
       final int nodeType;
       switch (compositeTypeSpec.getKey()) {
         case IASTCompositeTypeSpecifier.k_struct:
           nodeType = isTemplateDecl ? ICElement.C_TEMPLATE_STRUCT : ICElement.C_STRUCT;
           break;
         case IASTCompositeTypeSpecifier.k_union:
           nodeType = isTemplateDecl ? ICElement.C_TEMPLATE_UNION : ICElement.C_UNION;
           break;
         case ICPPASTCompositeTypeSpecifier.k_class:
           nodeType = isTemplateDecl ? ICElement.C_TEMPLATE_CLASS : ICElement.C_CLASS;
           break;
         default:
           assert false : "Unexpected composite type specifier"; // $NON-NLS-1$
           return PROCESS_CONTINUE;
       }
       push(nodeType, nodeName, startOffset);
     } else if (declSpec instanceof IASTEnumerationSpecifier) {
       IASTEnumerationSpecifier enumSpecifier = (IASTEnumerationSpecifier) declSpec;
       push(ICElement.C_ENUMERATION, getEnumerationName(enumSpecifier), startOffset);
     } else {
       IASTDeclarator[] declarators = simpleDecl.getDeclarators();
       for (int i = 0; i < declarators.length; i++) {
         IASTDeclarator declarator = declarators[i];
         int declStartOffset = declarators.length == 1 ? startOffset : getStartOffset(declarator);
         int declEndOffset = declarators.length == 1 ? endOffset : getEndOffset(declarator);
         final String nodeName = getDeclaratorName(declarator);
         if (declSpec.getStorageClass() == IASTDeclSpecifier.sc_typedef) {
           push(ICElement.C_TYPEDEF, nodeName, declStartOffset);
           pop(declEndOffset);
         } else if (declarator instanceof IASTFunctionDeclarator
             && !hasNestedPointerOperators(declarator)) {
           final int nodeType;
           if (inClassBody()) {
             nodeType =
                 isTemplateDecl
                     ? ICElement.C_TEMPLATE_METHOD_DECLARATION
                     : ICElement.C_METHOD_DECLARATION;
           } else {
             nodeType =
                 isTemplateDecl
                     ? ICElement.C_TEMPLATE_FUNCTION_DECLARATION
                     : ICElement.C_FUNCTION_DECLARATION;
           }
           push(nodeType, nodeName, declStartOffset);
           pop(declEndOffset);
         } else if (declarator != null) {
           final int nodeType;
           if (inClassBody()) {
             nodeType = ICElement.C_FIELD;
           } else {
             if (declSpec.getStorageClass() == IASTDeclSpecifier.sc_extern) {
               nodeType = ICElement.C_VARIABLE_DECLARATION;
             } else {
               nodeType = isTemplateDecl ? ICElement.C_TEMPLATE_VARIABLE : ICElement.C_VARIABLE;
             }
           }
           push(nodeType, nodeName, declStartOffset);
           pop(declEndOffset);
         }
       }
     }
   } else if (node instanceof IASTASMDeclaration) {
     // ignored
   } else if (node instanceof ICPPASTVisibilityLabel) {
     // ignored
   } else if (node instanceof ICPPASTNamespaceDefinition) {
     // handled below
   } else if (node instanceof ICPPASTNamespaceAlias) {
     // ignored
   } else if (node instanceof ICPPASTUsingDeclaration) {
     ICPPASTUsingDeclaration usingDecl = (ICPPASTUsingDeclaration) node;
     push(ICElement.C_USING, ASTStringUtil.getQualifiedName(usingDecl.getName()), startOffset);
     pop(endOffset);
   } else if (node instanceof ICPPASTUsingDirective) {
     ICPPASTUsingDirective usingDirective = (ICPPASTUsingDirective) node;
     push(
         ICElement.C_USING,
         ASTStringUtil.getQualifiedName(usingDirective.getQualifiedName()),
         startOffset);
     pop(endOffset);
   } else if (node instanceof ICPPASTLinkageSpecification) {
     // declarations get flattened
   } else if (node instanceof ICPPASTTemplateDeclaration) {
     // handled at child declaration level
   } else if (node instanceof ICPPASTTemplateSpecialization) {
     // ignored
   } else if (node instanceof ICPPASTExplicitTemplateInstantiation) {
     // ignored
   } else if (node instanceof IASTProblemDeclaration) {
     // ignored
   }
   return super.visit(node);
 }