diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
index e9580a9ab65..5530d8060ea 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
@@ -832,7 +832,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
}
private static int[] CTX_LINKAGES= {ILinkage.CPP_LINKAGE_ID, ILinkage.C_LINKAGE_ID};
- private ITranslationUnit getSourceContextTU(IIndex index, int style) {
+ public ITranslationUnit getSourceContextTU(IIndex index, int style) {
if (index != null && (style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) {
try {
fLanguageOfContext= null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties
index 5e828321b30..0d8d8cd8c22 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties
@@ -65,7 +65,7 @@ ASTProblemFactory.error.semantic.malformedExpression=Malformed expression
LineOffsetReconciler.error.couldNotResetReader=Could not reset Reader
-BaseProblemFactory.problemPattern={0} in file: {1}:{2, number, integer}.
+BaseProblemFactory.problemPattern={0} in file: {1}:{2, number, integer}
ASTProblemFactory.error.semantic.pst.ambiguousLookup=Ambiguity encountered during lookup: {0}
ASTProblemFactory.error.semantic.pst.invalidType=Invalid type encountered in: {0}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
index e9c6ac642bd..ab61429754a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
@@ -220,6 +220,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
return fIsSystemInclude;
}
+ @Override
IASTNode findSurroundingNode(int sequenceNumber, int length) {
final int nameSequencNumber= fName.getOffset();
final int nameEndSequencNumber= nameSequencNumber + fName.getLength();
@@ -258,6 +259,7 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
}
+ @Override
public String getContainingFilename() {
if (fName instanceof ASTBuiltinName) {
return fName.getContainingFilename();
@@ -281,6 +283,7 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
return (fName == n) ? r_definition : r_unclear;
}
+ @Override
IASTNode findSurroundingNode(int sequenceNumber, int length) {
final int nameSequencNumber= fName.getOffset();
final int nameEndSequencNumber= nameSequencNumber + fName.getLength();
@@ -312,6 +315,11 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
}
return null;
}
+
+ @Override
+ public String toString() {
+ return getName().toString() + '=' + getExpansion();
+ }
}
class ASTMacroParameter extends ASTPreprocessorNode implements IASTFunctionStyleMacroParameter {
@@ -357,6 +365,25 @@ class ASTFunctionStyleMacroDefinition extends ASTMacroDefinition implements IAST
}
public void addParameter(IASTFunctionStyleMacroParameter parm) {assert false;}
+
+ @Override
+ public String toString() {
+ StringBuilder result= new StringBuilder();
+ result.append(getName().toCharArray());
+ result.append('(');
+ boolean needComma= false;
+ for (IASTFunctionStyleMacroParameter param : getParameters()) {
+ if (needComma) {
+ result.append(',');
+ }
+ result.append(param.getParameter());
+ needComma= true;
+ }
+ result.append(')');
+ result.append('=');
+ result.append(getExpansion());
+ return result.toString();
+ }
}
@@ -371,6 +398,7 @@ class ASTUndef extends ASTPreprocessorNode implements IASTPreprocessorUndefState
return fName;
}
+ @Override
IASTNode findSurroundingNode(int sequenceNumber, int length) {
final int nameSequencNumber= fName.getOffset();
final int nameEndSequencNumber= nameSequencNumber + fName.getLength();
@@ -457,6 +485,7 @@ class ASTFileLocation implements IASTFileLocation {
return fLocationCtx.getSource(fOffset, fLength);
}
+ @Override
public String toString() {
return getFileName() + "[" + fOffset + "," + (fOffset+fLength) + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
}
@@ -511,6 +540,7 @@ class ASTMacroExpansionLocation implements IASTMacroExpansion {
return fOffset;
}
+ @Override
public String toString() {
return fContext.getMacroDefinition().getName().toString() + "[" + fOffset + "," + (fOffset+fLength) + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
}
diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties
index e68a00c93d9..5d088da9112 100644
--- a/core/org.eclipse.cdt.ui/plugin.properties
+++ b/core/org.eclipse.cdt.ui/plugin.properties
@@ -380,6 +380,7 @@ RebuildIndex.name=&Rebuild
SyncIndex.name=&Update with Modified Files
FreshenIndex.name=&Freshen All Files
SearchUnresolvedIncludes.name=Search for Unresolved &Includes
+CreateParserLog.name=Create Parser &Log File
indexerPage.name = Indexer Page
proposalFilter.name = Code Completion Proposal Filter
diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml
index 970095ff92c..d9e82604f89 100644
--- a/core/org.eclipse.cdt.ui/plugin.xml
+++ b/core/org.eclipse.cdt.ui/plugin.xml
@@ -824,6 +824,28 @@
+
+
+
+
+
+
+
+
+
+
@@ -884,6 +907,7 @@
+
fProblems= new ArrayList();
+ List fProblemBindings= new ArrayList();
+ List fExceptions= new ArrayList();
+
+ MyVisitor() {
+ shouldVisitProblems= true;
+ shouldVisitNames= true;
+ }
+
+ @Override
+ public int visit(IASTProblem problem) {
+ fProblems.add(problem);
+ return PROCESS_SKIP;
+ }
+
+ @Override
+ public int visit(IASTName name) {
+ if (name instanceof ICPPASTQualifiedName) {
+ return PROCESS_CONTINUE;
+ }
+ try {
+ IBinding binding= name.resolveBinding();
+ if (binding instanceof IProblemBinding) {
+ fProblemBindings.add((IProblemBinding) binding);
+ }
+ } catch (RuntimeException e) {
+ fExceptions.add(e);
+ }
+ return PROCESS_CONTINUE;
+ }
+ }
+
+ private ISelection fSelection;
+ private IWorkbenchPartSite fSite;
+
+ public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+ fSite= targetPart.getSite();
+ }
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ fSelection = selection;
+ }
+
+ public void run(IAction action) {
+ if (!(fSelection instanceof IStructuredSelection))
+ return;
+
+ final String title= action.getText().replace("&", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ IStructuredSelection cElements= SelectionConverter.convertSelectionToCElements(fSelection);
+ Iterator i= cElements.iterator();
+ ArrayList tuSelection= new ArrayList();
+ while (i.hasNext()) {
+ Object o= i.next();
+ if (o instanceof ITranslationUnit) {
+ tuSelection.add((ITranslationUnit) o);
+ }
+ }
+ ITranslationUnit[] tuArray= tuSelection.toArray(new ITranslationUnit[tuSelection.size()]);
+ if (tuArray.length == 0) {
+ return;
+ }
+ FileDialog dlg= new FileDialog(fSite.getShell(), SWT.SAVE);
+ dlg.setText(title);
+ dlg.setFilterExtensions(new String[]{"*.log"}); //$NON-NLS-1$
+ String path= null;
+ while(path == null) {
+ path= dlg.open();
+ if (path == null)
+ return;
+
+ File file= new File(path);
+ if (file.exists()) {
+ if (!file.canWrite()) {
+ final String msg= NLS.bind(ActionMessages.getString("CreateParserLogAction.readOnlyFile"), path); //$NON-NLS-1$
+ MessageDialog.openError(fSite.getShell(), title, msg);
+ path= null;
+ }
+ else {
+ final String msg = NLS.bind(ActionMessages.getString("CreateParserLogAction.existingFile"), path); //$NON-NLS-1$
+ if (!MessageDialog.openQuestion(fSite.getShell(), title, msg)) {
+ path= null;
+ }
+ }
+ }
+ }
+
+ try {
+ PrintStream out= new PrintStream(path);
+ try {
+ boolean needsep= false;
+ for (ITranslationUnit tu : tuArray) {
+ if (needsep) {
+ out.println(); out.println();
+ }
+ createLog(out, tu, new NullProgressMonitor());
+ needsep= true;
+ }
+ }
+ finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ MessageDialog.openError(fSite.getShell(), action.getText(), e.getMessage());
+ }
+ }
+
+ private void createLog(final PrintStream out, final ITranslationUnit tu, IProgressMonitor pm) {
+ ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_YES, pm, new ASTCache.ASTRunnable() {
+ public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
+ return createLog(out, tu, lang, ast);
+ }
+ });
+ }
+
+ protected IStatus createLog(PrintStream out, ITranslationUnit tu, ILanguage lang, IASTTranslationUnit ast) {
+ IStatus status = Status.OK_STATUS;
+ final ICProject cproject = tu.getCProject();
+ final String projectName= cproject == null ? null : cproject.getElementName();
+
+ ITranslationUnit ctx= tu;
+ if (tu instanceof TranslationUnit) {
+ TranslationUnit itu= (TranslationUnit) tu;
+ ctx= itu.getSourceContextTU(ast.getIndex(), ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT);
+ }
+ final ExtendedScannerInfo scfg= new ExtendedScannerInfo(ctx.getScannerInfo(true));
+ final String indent= " "; //$NON-NLS-1$
+ final MyVisitor visitor= new MyVisitor();
+ ast.accept(visitor);
+
+ out.println("Project: " + projectName); //$NON-NLS-1$
+ out.println("Index Version: " + PDOM.CURRENT_VERSION); //$NON-NLS-1$
+ out.println("File: " + tu.getLocationURI()); //$NON-NLS-1$
+ out.println("Context: " + ctx.getLocationURI()); //$NON-NLS-1$
+ out.println("Language: " + lang.getName()); //$NON-NLS-1$
+ out.println();
+ out.println("Include Search Path (option -I):"); //$NON-NLS-1$
+ output(out, indent, scfg.getIncludePaths());
+ out.println();
+ out.println("Local Include Search Path (option -iquote):"); //$NON-NLS-1$
+ output(out, indent, scfg.getLocalIncludePath());
+ out.println();
+ out.println("Preincluded files (option -include):"); //$NON-NLS-1$
+ output(out, indent, scfg.getIncludeFiles());
+ out.println();
+ out.println("Preincluded macro files (option -imacros):"); //$NON-NLS-1$
+ output(out, indent, scfg.getMacroFiles());
+ out.println();
+ out.println("Macro definitions (option -D):"); //$NON-NLS-1$
+ HashSet reported= new HashSet();
+ output(out, indent, scfg.getDefinedSymbols(), reported);
+ out.println();
+ out.println("Macro definitions (from configuration + headers in index):"); //$NON-NLS-1$
+ output(out, indent, ast.getBuiltinMacroDefinitions(), reported);
+ out.println();
+ out.println("Macro definitions (from files actually parsed):"); //$NON-NLS-1$
+ output(out, indent, ast.getMacroDefinitions(), reported);
+
+ out.println();
+ out.println("Unresolved includes (from headers in index):"); //$NON-NLS-1$
+ try {
+ outputUnresolvedIncludes(cproject, ast.getIndex(), out, indent, ast.getIncludeDirectives(), ast.getLinkage().getLinkageID());
+ } catch (CoreException e) {
+ status= e.getStatus();
+ }
+
+ out.println();
+ out.println("Scanner problems:"); //$NON-NLS-1$
+ output(out, indent, ast.getPreprocessorProblems());
+
+ out.println();
+ out.println("Parser problems:"); //$NON-NLS-1$
+ output(out, indent, visitor.fProblems.toArray(new IASTProblem[visitor.fProblems.size()]));
+
+ out.println();
+ out.println("Unresolved names:"); //$NON-NLS-1$
+ output(out, indent, visitor.fProblemBindings);
+
+ out.println();
+ out.println("Exceptions in name resolution:"); //$NON-NLS-1$
+ output(out, visitor.fExceptions);
+
+ return status;
+ }
+
+ private void outputUnresolvedIncludes(ICProject prj, IIndex index, PrintStream out, String indent,
+ IASTPreprocessorIncludeStatement[] includeDirectives, int linkageID) throws CoreException {
+ ASTFilePathResolver resolver= new ProjectIndexerInputAdapter(prj);
+ for (IASTPreprocessorIncludeStatement include : includeDirectives) {
+ if (include.isActive() && include.isResolved()) {
+ outputUnresolvedIncludes(index, out, indent, resolver.resolveASTPath(include.getPath()), linkageID);
+ }
+ }
+ }
+
+ private void outputUnresolvedIncludes(IIndex index, PrintStream out, String indent,
+ IIndexFileLocation ifl, int linkageID) throws CoreException {
+ IIndexFile ifile= index.getFile(linkageID, ifl);
+ if (ifile == null) {
+ out.println(indent + ifl.getURI() + " is not indexed"); //$NON-NLS-1$
+ }
+ else {
+ IIndexInclude[] includes = ifile.getIncludes();
+ for (IIndexInclude inc : includes) {
+ if (inc.isActive()) {
+ if (inc.isResolved()) {
+ outputUnresolvedIncludes(index, out, indent, inc.getIncludesLocation(), linkageID);
+ }
+ else {
+ out.println(indent + "Unresolved inclusion: " + inc.getName() + " in file " + //$NON-NLS-1$//$NON-NLS-2$
+ inc.getIncludedByLocation().getURI());
+ }
+ }
+ }
+ }
+ }
+
+ private void output(PrintStream out, String indent, String[] list) {
+ for (String line : list) {
+ out.println(indent + line);
+ }
+ }
+
+ private void output(PrintStream out, String indent, Map definedSymbols, HashSet reported) {
+ for (Entry entry : definedSymbols.entrySet()) {
+ final String macro = entry.getKey() + '=' + entry.getValue();
+ if (reported.add(macro)) {
+ out.println(indent + macro);
+ }
+ }
+ }
+
+ private void output(PrintStream out, String indent, IASTPreprocessorMacroDefinition[] defs, HashSet reported) {
+ for (IASTPreprocessorMacroDefinition def : defs) {
+ String macro= def.toString();
+ if (reported.add(macro)) {
+ out.println(indent + macro);
+ }
+ }
+ }
+
+ private void output(PrintStream out, String indent, IASTProblem[] preprocessorProblems) {
+ for (IASTProblem problem : preprocessorProblems) {
+ out.println(indent + problem.getMessage());
+ }
+ }
+
+ private void output(PrintStream out, String indent, List list) {
+ for (IProblemBinding problem : list) {
+ String file= problem.getFileName();
+ int line = problem.getLineNumber();
+ out.println(indent + problem.getMessage() + " in file " + file + ':' + line); //$NON-NLS-1$
+ }
+ }
+
+ private void output(PrintStream out, List list) {
+ for (Exception problem : list) {
+ problem.printStackTrace(out);
+ }
+ }
+}