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 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); }
// _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); }