Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tobias Hunger
qt-creator
Commits
17f17851
Commit
17f17851
authored
Dec 08, 2008
by
hjk
Browse files
Merge branch '0.9.1-beta' of git@scm.dev.nokia.troll.no:creator/mainline into 0.9.1-beta
parents
e4796731
1f8ce02d
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/plugins/cpptools/cppmodelmanager.cpp
View file @
17f17851
...
...
@@ -31,7 +31,6 @@
**
***************************************************************************/
#define _SCL_SECURE_NO_WARNINGS 1
#include
"pp.h"
#include
"cppmodelmanager.h"
...
...
@@ -70,11 +69,10 @@
#include
<QTime>
#include
<QDebug>
using
namespace
CppTools
;
using
namespace
CppTools
::
Internal
;
using
namespace
CPlusPlus
;
namespace
CppTools
{
namespace
Internal
{
static
const
char
pp_configuration_file
[]
=
"<configuration>"
;
static
const
char
pp_configuration
[]
=
...
...
@@ -106,299 +104,328 @@ static const char pp_configuration[] =
"#define __declspec(a)
\n
"
"#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method
\n
"
;
namespace
CppTools
{
namespace
Internal
{
class
CppPreprocessor
:
public
rpp
::
Client
{
public:
CppPreprocessor
(
QPointer
<
CppModelManager
>
modelManager
)
:
m_modelManager
(
modelManager
),
m_documents
(
modelManager
->
documents
()),
m_proc
(
this
,
env
)
{
}
CppPreprocessor
(
QPointer
<
CppModelManager
>
modelManager
);
void
setWorkingCopy
(
const
QMap
<
QString
,
QByteArray
>
&
workingCopy
);
void
setIncludePaths
(
const
QStringList
&
includePaths
);
void
setFrameworkPaths
(
const
QStringList
&
frameworkPaths
);
void
addIncludePath
(
const
QString
&
path
);
void
setProjectFiles
(
const
QStringList
&
files
);
void
run
(
QString
&
fileName
);
void
operator
()(
QString
&
fileName
);
void
setWorkingCopy
(
const
QMap
<
QString
,
QByteArray
>
&
workingCopy
)
{
m_workingCopy
=
workingCopy
;
}
protected:
CPlusPlus
::
Document
::
Ptr
switchDocument
(
CPlusPlus
::
Document
::
Ptr
doc
);
bool
includeFile
(
const
QString
&
absoluteFilePath
,
QByteArray
*
result
);
QByteArray
tryIncludeFile
(
QString
&
fileName
,
IncludeType
type
);
void
mergeEnvironment
(
CPlusPlus
::
Document
::
Ptr
doc
);
void
mergeEnvironment
(
CPlusPlus
::
Document
::
Ptr
doc
,
QSet
<
QString
>
*
processed
);
virtual
void
macroAdded
(
const
QByteArray
&
macroName
,
const
QByteArray
&
macroText
);
virtual
void
startExpandingMacro
(
unsigned
offset
,
const
rpp
::
Macro
&
macro
,
const
QByteArray
&
originalText
);
virtual
void
stopExpandingMacro
(
unsigned
offset
,
const
rpp
::
Macro
&
macro
);
virtual
void
startSkippingBlocks
(
unsigned
offset
);
virtual
void
stopSkippingBlocks
(
unsigned
offset
);
virtual
void
sourceNeeded
(
QString
&
fileName
,
IncludeType
type
);
private:
QPointer
<
CppModelManager
>
m_modelManager
;
CppModelManager
::
DocumentTable
m_documents
;
rpp
::
Environment
env
;
rpp
::
pp
m_proc
;
QStringList
m_includePaths
;
QStringList
m_systemIncludePaths
;
QMap
<
QString
,
QByteArray
>
m_workingCopy
;
QStringList
m_projectFiles
;
QStringList
m_frameworkPaths
;
QSet
<
QString
>
m_included
;
CPlusPlus
::
Document
::
Ptr
m_currentDoc
;
};
void
setIncludePaths
(
const
QStringList
&
includePaths
)
{
m_includePaths
=
includePaths
;
}
}
// namespace Internal
}
// namespace CppTools
void
setFrameworkPaths
(
const
QStringList
&
frameworkPaths
)
{
m_frameworkPaths
=
frameworkPaths
;
}
CppPreprocessor
::
CppPreprocessor
(
QPointer
<
CppModelManager
>
modelManager
)
:
m_modelManager
(
modelManager
),
m_documents
(
modelManager
->
documents
()),
m_proc
(
this
,
env
)
{
}
void
addIncludePath
(
const
QString
&
path
)
{
m_includePaths
.
append
(
path
)
;
}
void
CppPreprocessor
::
setWorkingCopy
(
const
QMap
<
QString
,
QByteArray
>
&
workingCopy
)
{
m_workingCopy
=
workingCopy
;
}
void
setProjectFile
s
(
const
QStringList
&
file
s
)
{
m_projectFiles
=
file
s
;
}
void
CppPreprocessor
::
setIncludePath
s
(
const
QStringList
&
includePath
s
)
{
m_includePaths
=
includePath
s
;
}
void
run
(
QString
&
fileName
)
{
sourceNeeded
(
fileName
,
IncludeGlobal
)
;
}
void
CppPreprocessor
::
setFrameworkPaths
(
const
QStringList
&
frameworkPaths
)
{
m_frameworkPaths
=
frameworkPaths
;
}
void
operator
()(
QString
&
fileName
)
{
run
(
fileName
);
}
void
CppPreprocessor
::
addIncludePath
(
const
QString
&
path
)
{
m_includePaths
.
append
(
path
);
}
protected:
bool
includeFile
(
const
QString
&
absoluteFilePath
,
QByteArray
*
result
)
{
if
(
absoluteFilePath
.
isEmpty
()
||
m_included
.
contains
(
absoluteFilePath
))
{
return
true
;
}
void
CppPreprocessor
::
setProjectFiles
(
const
QStringList
&
files
)
{
m_projectFiles
=
files
;
}
if
(
m_workingCopy
.
contains
(
absoluteFilePath
))
{
m_included
.
insert
(
absoluteFilePath
);
*
result
=
m_workingCopy
.
value
(
absoluteFilePath
);
return
true
;
}
void
CppPreprocessor
::
run
(
QString
&
fileName
)
{
sourceNeeded
(
fileName
,
IncludeGlobal
);
}
QFileInfo
fileInfo
(
absoluteFilePath
);
if
(
!
fileInfo
.
isFile
())
return
false
;
QFile
file
(
absoluteFilePath
);
if
(
file
.
open
(
QFile
::
ReadOnly
))
{
m_included
.
insert
(
absoluteFilePath
);
QTextStream
stream
(
&
file
);
const
QString
contents
=
stream
.
readAll
();
*
result
=
contents
.
toUtf8
();
file
.
close
();
return
true
;
}
void
CppPreprocessor
::
operator
()(
QString
&
fileName
)
{
run
(
fileName
);
}
bool
CppPreprocessor
::
includeFile
(
const
QString
&
absoluteFilePath
,
QByteArray
*
result
)
{
if
(
absoluteFilePath
.
isEmpty
()
||
m_included
.
contains
(
absoluteFilePath
))
{
return
true
;
}
if
(
m_workingCopy
.
contains
(
absoluteFilePath
))
{
m_included
.
insert
(
absoluteFilePath
);
*
result
=
m_workingCopy
.
value
(
absoluteFilePath
);
return
true
;
}
QFileInfo
fileInfo
(
absoluteFilePath
);
if
(
!
fileInfo
.
isFile
())
return
false
;
QFile
file
(
absoluteFilePath
);
if
(
file
.
open
(
QFile
::
ReadOnly
))
{
m_included
.
insert
(
absoluteFilePath
);
QTextStream
stream
(
&
file
);
const
QString
contents
=
stream
.
readAll
();
*
result
=
contents
.
toUtf8
();
file
.
close
();
return
true
;
}
QByteArray
tryIncludeFile
(
QString
&
fileName
,
IncludeType
type
)
{
QFileInfo
fileInfo
(
fileName
);
if
(
fileName
==
QLatin1String
(
pp_configuration_file
)
||
fileInfo
.
isAbsolute
())
{
QByteArray
contents
;
includeFile
(
fileName
,
&
contents
);
return
false
;
}
QByteArray
CppPreprocessor
::
tryIncludeFile
(
QString
&
fileName
,
IncludeType
type
)
{
QFileInfo
fileInfo
(
fileName
);
if
(
fileName
==
QLatin1String
(
pp_configuration_file
)
||
fileInfo
.
isAbsolute
())
{
QByteArray
contents
;
includeFile
(
fileName
,
&
contents
);
return
contents
;
}
if
(
type
==
IncludeLocal
&&
m_currentDoc
)
{
QFileInfo
currentFileInfo
(
m_currentDoc
->
fileName
());
QString
path
=
currentFileInfo
.
absolutePath
();
path
+=
QLatin1Char
(
'/'
);
path
+=
fileName
;
path
=
QDir
::
cleanPath
(
path
);
QByteArray
contents
;
if
(
includeFile
(
path
,
&
contents
))
{
fileName
=
path
;
return
contents
;
}
}
if
(
type
==
IncludeLocal
&&
m_currentDoc
)
{
QFileInfo
currentFileInfo
(
m_currentDoc
->
fileName
());
QString
path
=
currentFileInfo
.
absolutePath
();
path
+=
QLatin1Char
(
'/'
);
path
+=
fileName
;
path
=
QDir
::
cleanPath
(
path
);
QByteArray
contents
;
if
(
includeFile
(
path
,
&
contents
))
{
fileName
=
path
;
return
contents
;
}
foreach
(
const
QString
&
includePath
,
m_includePaths
)
{
QString
path
=
includePath
;
path
+=
QLatin1Char
(
'/'
);
path
+=
fileName
;
path
=
QDir
::
cleanPath
(
path
);
QByteArray
contents
;
if
(
includeFile
(
path
,
&
contents
))
{
fileName
=
path
;
return
contents
;
}
}
foreach
(
const
QString
&
includePath
,
m_
include
P
aths
)
{
QString
path
=
i
ncludePath
;
path
+
=
QLatin1Char
(
'/'
)
;
path
+=
fileName
;
path
=
QDir
::
cleanPath
(
path
)
;
QByteArray
contents
;
if
(
includeFile
(
path
,
&
contents
))
{
fileName
=
path
;
return
contents
;
}
// look in the system
include
p
aths
foreach
(
const
QString
&
includePath
,
m_systemI
ncludePath
s
)
{
QString
path
=
includePath
;
path
+=
QLatin1Char
(
'/'
)
;
path
+
=
fileName
;
path
=
QDir
::
cleanPath
(
path
)
;
QByteArray
contents
;
if
(
includeFile
(
path
,
&
contents
))
{
fileName
=
path
;
return
contents
;
}
}
int
index
=
fileName
.
indexOf
(
QLatin1Char
(
'/'
));
if
(
index
!=
-
1
)
{
QString
frameworkName
=
fileName
.
left
(
index
);
QString
name
=
fileName
.
mid
(
index
+
1
);
// look in the system include paths
foreach
(
const
QString
&
includePath
,
m_systemIncludePaths
)
{
QString
path
=
includePath
;
foreach
(
const
QString
&
frameworkPath
,
m_frameworkPaths
)
{
QString
path
=
frameworkPath
;
path
+=
QLatin1Char
(
'/'
);
path
+=
fileName
;
path
=
QDir
::
cleanPath
(
path
);
path
+=
frameworkName
;
path
+=
QLatin1String
(
".framework/Headers/"
);
path
+=
name
;
QByteArray
contents
;
if
(
includeFile
(
path
,
&
contents
))
{
fileName
=
path
;
return
contents
;
}
}
}
int
index
=
fileName
.
indexOf
(
QLatin1Char
(
'/'
));
if
(
index
!=
-
1
)
{
QString
frameworkName
=
fileName
.
left
(
index
);
QString
name
=
fileName
.
mid
(
index
+
1
);
foreach
(
const
QString
&
frameworkPath
,
m_frameworkPaths
)
{
QString
path
=
frameworkPath
;
path
+=
QLatin1Char
(
'/'
);
path
+=
frameworkName
;
path
+=
QLatin1String
(
".framework/Headers/"
);
path
+=
name
;
QByteArray
contents
;
if
(
includeFile
(
path
,
&
contents
))
{
fileName
=
path
;
return
contents
;
}
}
QString
path
=
fileName
;
if
(
path
.
at
(
0
)
!=
QLatin1Char
(
'/'
))
path
.
prepend
(
QLatin1Char
(
'/'
));
foreach
(
const
QString
&
projectFile
,
m_projectFiles
)
{
if
(
projectFile
.
endsWith
(
path
))
{
fileName
=
projectFile
;
QByteArray
contents
;
includeFile
(
fileName
,
&
contents
);
return
contents
;
}
}
QString
path
=
fileName
;
if
(
path
.
at
(
0
)
!=
QLatin1Char
(
'/'
))
path
.
prepend
(
QLatin1Char
(
'/'
));
//qDebug() << "**** file" << fileName << "not found!"
;
return
QByteArray
();
}
foreach
(
const
QString
&
projectFile
,
m_projectFiles
)
{
if
(
projectFile
.
endsWith
(
path
))
{
fileName
=
projectFile
;
QByteArray
contents
;
includeFile
(
fileName
,
&
contents
);
return
contents
;
}
}
void
CppPreprocessor
::
macroAdded
(
const
QByteArray
&
macroName
,
const
QByteArray
&
macroText
)
{
if
(
!
m_currentDoc
)
return
;
//qDebug() << "**** file" << fileName << "not found!";
return
QByteArray
();
}
m_currentDoc
->
appendMacro
(
macroName
,
macroText
);
}
virtual
void
macroAdded
(
const
QByteArray
&
macroName
,
const
QByteArray
&
macroText
)
{
if
(
!
m_currentDoc
)
return
;
void
CppPreprocessor
::
startExpandingMacro
(
unsigned
offset
,
const
rpp
::
Macro
&
,
const
QByteArray
&
originalText
)
{
if
(
!
m_currentDoc
)
return
;
m_currentDoc
->
appendMacro
(
macroName
,
macroText
);
}
//qDebug() << "start expanding:" << macro.name << "text:" << originalText;
m_currentDoc
->
addMacroUse
(
offset
,
originalText
.
length
());
}
virtual
void
startExpandingMacro
(
unsigned
offset
,
const
rpp
::
Macro
&
,
const
QByteArray
&
originalText
)
{
if
(
!
m_currentDoc
)
return
;
//qDebug() << "start expanding:" << macro.name << "text:" << originalText;
m_currentDoc
->
addMacroUse
(
offset
,
originalText
.
length
());
}
void
CppPreprocessor
::
stopExpandingMacro
(
unsigned
,
const
rpp
::
Macro
&
)
{
if
(
!
m_currentDoc
)
return
;
virtual
void
stopExpandingMacro
(
unsigned
,
const
rpp
::
Macro
&
)
{
if
(
!
m_currentDoc
)
return
;
//qDebug() << "stop expanding:" << macro.name;
}
//qDebug() << "stop expanding:" << macro.name;
}
void
CppPreprocessor
::
mergeEnvironment
(
Document
::
Ptr
doc
)
{
QSet
<
QString
>
processed
;
mergeEnvironment
(
doc
,
&
processed
);
}
void
mergeEnvironment
(
Document
::
Ptr
doc
)
{
QSet
<
QString
>
processed
;
mergeEnvironment
(
doc
,
&
processed
);
}
void
CppPreprocessor
::
mergeEnvironment
(
Document
::
Ptr
doc
,
QSet
<
QString
>
*
processed
)
{
if
(
!
doc
)
return
;
void
mergeEnvironment
(
Document
::
Ptr
doc
,
QSet
<
QString
>
*
processed
)
{
if
(
!
doc
)
return
;
const
QString
fn
=
doc
->
fileName
();
const
QString
fn
=
doc
->
fileName
();
if
(
processed
->
contains
(
fn
))
return
;
if
(
processed
->
contains
(
fn
))
return
;
processed
->
insert
(
fn
);
processed
->
insert
(
fn
);
foreach
(
QString
includedFile
,
doc
->
includedFiles
())
mergeEnvironment
(
m_documents
.
value
(
includedFile
),
processed
);
foreach
(
QString
includedFile
,
doc
->
includedFile
s
()
)
mergeEnvironment
(
m_documents
.
value
(
includedFile
),
processed
);
const
QByteArray
macros
=
doc
->
definedMacro
s
()
;
QByteArray
localFileName
=
doc
->
fileName
().
toUtf8
(
);
const
QByteArray
macros
=
doc
->
definedMacros
();
QByteArray
localFileName
=
doc
->
fileName
().
toUtf8
();
QByteArray
dummy
;
m_proc
(
localFileName
,
macros
,
&
dummy
);
}
QByteArray
dummy
;
m_proc
(
localFileName
,
macros
,
&
dummy
);
}
void
CppPreprocessor
::
startSkippingBlocks
(
unsigned
offset
)
{
//qDebug() << "start skipping blocks:" << offset;
if
(
m_currentDoc
)
m_currentDoc
->
startSkippingBlocks
(
offset
);
}
virtual
void
start
SkippingBlocks
(
unsigned
offset
)
{
//qDebug() << "st
art
skipping blocks:" << offset;
if
(
m_currentDoc
)
m_currentDoc
->
st
art
SkippingBlocks
(
offset
);
}
void
CppPreprocessor
::
stop
SkippingBlocks
(
unsigned
offset
)
{
//qDebug() << "st
op
skipping blocks:" << offset;
if
(
m_currentDoc
)
m_currentDoc
->
st
op
SkippingBlocks
(
offset
);
}
virtual
void
stopSkippingBlocks
(
unsigned
offset
)
{
//qDebug() << "stop skipping blocks:" << offset;
if
(
m_currentDoc
)
m_currentDoc
->
stopSkippingBlocks
(
offset
);
}
void
CppPreprocessor
::
sourceNeeded
(
QString
&
fileName
,
IncludeType
type
)
{
if
(
fileName
.
isEmpty
())
return
;
virtual
void
sourceNeeded
(
QString
&
fileName
,
IncludeType
type
)
{
if
(
fileName
.
isEmpty
())
return
;
QByteArray
contents
=
tryIncludeFile
(
fileName
,
type
);
if
(
m_currentDoc
)
{
m_currentDoc
->
addIncludeFile
(
fileName
);
if
(
contents
.
isEmpty
()
&&
!
QFileInfo
(
fileName
).
isAbsolute
())
{
QString
msg
;
msg
+=
fileName
;
msg
+=
QLatin1String
(
": No such file or directory"
);
Document
::
DiagnosticMessage
d
(
Document
::
DiagnosticMessage
::
Warning
,
m_currentDoc
->
fileName
(),
env
.
currentLine
,
/*column = */
0
,
msg
);
m_currentDoc
->
addDiagnosticMessage
(
d
);
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
}
QByteArray
contents
=
tryIncludeFile
(
fileName
,
type
);
if
(
m_currentDoc
)
{
m_currentDoc
->
addIncludeFile
(
fileName
);
if
(
contents
.
isEmpty
()
&&
!
QFileInfo
(
fileName
).
isAbsolute
())
{
QString
msg
;
msg
+=
fileName
;
msg
+=
QLatin1String
(
": No such file or directory"
);
Document
::
DiagnosticMessage
d
(
Document
::
DiagnosticMessage
::
Warning
,
m_currentDoc
->
fileName
(),
env
.
currentLine
,
/*column = */
0
,
msg
);
m_currentDoc
->
addDiagnosticMessage
(
d
);
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
}
}
if
(
!
contents
.
isEmpty
())
{
Document
::
Ptr
cachedDoc
=
m_documents
.
value
(
fileName
);
if
(
cachedDoc
&&
m_currentDoc
)
{
mergeEnvironment
(
cachedDoc
);
}
else
{
Document
::
Ptr
previousDoc
=
switchDocument
(
Document
::
create
(
fileName
));
if
(
!
contents
.
isEmpty
())
{
Document
::
Ptr
cachedDoc
=
m_documents
.
value
(
fileName
);
if
(
cachedDoc
&&
m_currentDoc
)
{
mergeEnvironment
(
cachedDoc
);
}
else
{
Document
::
Ptr
previousDoc
=
switchDocument
(
Document
::
create
(
fileName
));
const
QByteArray
previousFile
=
env
.
current_file
;
const
unsigned
previousLine
=
env
.
currentLine
;
const
QByteArray
previousFile
=
env
.
current_file
;
const
unsigned
previousLine
=
env
.
currentLine
;
env
.
current_file
=
QByteArray
(
m_currentDoc
->
translationUnit
()
->
fileName
(),
m_currentDoc
->
translationUnit
()
->
fileNameLength
());
env
.
current_file
=
QByteArray
(
m_currentDoc
->
translationUnit
()
->
fileName
(),
m_currentDoc
->
translationUnit
()
->
fileNameLength
());
QByteArray
preprocessedCode
;
m_proc
(
contents
,
&
preprocessedCode
);
//qDebug() << preprocessedCode;
QByteArray
preprocessedCode
;
m_proc
(
contents
,
&
preprocessedCode
);
//qDebug() << preprocessedCode;
env
.
current_file
=
previousFile
;
env
.
currentLine
=
previousLine
;
env
.
current_file
=
previousFile
;
env
.
currentLine
=
previousLine
;
m_currentDoc
->
setSource
(
preprocessedCode
);
m_currentDoc
->
parse
();
m_currentDoc
->
check
();
m_currentDoc
->
releaseTranslationUnit
();
// release the AST and the token stream.
m_currentDoc
->
setSource
(
preprocessedCode
);
m_currentDoc
->
parse
();
m_currentDoc
->
check
();
m_currentDoc
->
releaseTranslationUnit
();
// release the AST and the token stream.
if
(
m_modelManager
)
m_modelManager
->
emitDocumentUpdated
(
m_currentDoc
);
(
void
)
switchDocument
(
previousDoc
);
}
if
(
m_modelManager
)
m_modelManager
->
emitDocumentUpdated
(
m_currentDoc
);
(
void
)
switchDocument
(
previousDoc
);
}
}
}
Document
::
Ptr
switchDocument
(
Document
::
Ptr
doc
)
{
Document
::
Ptr
previousDoc
=
m_currentDoc
;
m_currentDoc
=
doc
;
return
previousDoc
;
}
private:
QPointer
<
CppModelManager
>
m_modelManager
;
CppModelManager
::
DocumentTable
m_documents
;
rpp
::
Environment
env
;
rpp
::
pp
m_proc
;
QStringList
m_includePaths
;
QStringList
m_systemIncludePaths
;
QMap
<
QString
,
QByteArray
>
m_workingCopy
;
QStringList
m_projectFiles
;
QStringList
m_frameworkPaths
;
QSet
<
QString
>
m_included
;
Document
::
Ptr
m_currentDoc
;
};
}
// namespace Internal
}
// namespace CppTools
Document
::
Ptr
CppPreprocessor
::
switchDocument
(
Document
::
Ptr
doc
)
{
Document
::
Ptr
previousDoc
=
m_currentDoc
;
m_currentDoc
=
doc
;
return
previousDoc
;
}
using
namespace
CppTools
;
using
namespace
CppTools
::
Internal
;
/*!
\class CppTools::CppModelManager
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment