Partial fix for #5555. Remember function attributes: pure, const, constructor, destructor

This commit is contained in:
Robert Reif 2014-03-14 05:40:17 +01:00 committed by Daniel Marjamäki
parent 5698f7b337
commit 8c993c1363
6 changed files with 90 additions and 4 deletions

View File

@ -1249,8 +1249,15 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
{
Function* function = 0;
for (std::list<Function>::iterator i = scope->functionList.begin(); i != scope->functionList.end(); ++i) {
if (i->tokenDef->str() == tok->str() && Function::argsMatch(scope, i->argDef->next(), argStart->next(), "", 0))
if (i->tokenDef->str() == tok->str() && Function::argsMatch(scope, i->argDef->next(), argStart->next(), "", 0)) {
function = &*i;
// copy attributes from function prototype to function
const_cast<Token *>(tok)->isAttributeConstructor(i->tokenDef->isAttributeConstructor());
const_cast<Token *>(tok)->isAttributeDestructor(i->tokenDef->isAttributeDestructor());
const_cast<Token *>(tok)->isAttributePure(i->tokenDef->isAttributePure());
const_cast<Token *>(tok)->isAttributeConst(i->tokenDef->isAttributeConst());
break;
}
}
if (!function)

View File

@ -562,6 +562,18 @@ public:
bool isDestructor() const {
return type==eDestructor;
}
bool isAttributeConstructor() const {
return tokenDef->isAttributeConstructor();
}
bool isAttributeDestructor() const {
return tokenDef->isAttributeDestructor();
}
bool isAttributePure() const {
return tokenDef->isAttributePure();
}
bool isAttributeConst() const {
return tokenDef->isAttributeConst();
}
const Token *tokenDef; // function name token in class definition
const Token *argDef; // function argument start '(' in class definition

View File

@ -51,7 +51,10 @@ Token::Token(Token **t) :
_isStandardType(false),
_isExpandedMacro(false),
_isAttributeConstructor(false),
_isAttributeDestructor(false),
_isAttributeUnused(false),
_isAttributePure(false),
_isAttributeConst(false),
_astOperand1(nullptr),
_astOperand2(nullptr),
_astParent(nullptr)
@ -199,7 +202,10 @@ void Token::deleteThis()
_isStandardType = _next->_isStandardType;
_isExpandedMacro = _next->_isExpandedMacro;
_isAttributeConstructor = _next->_isAttributeConstructor;
_isAttributeDestructor = _next->_isAttributeDestructor;
_isAttributeUnused = _next->_isAttributeUnused;
_isAttributePure = _next->_isAttributePure;
_isAttributeConst = _next->_isAttributeConst;
_varId = _next->_varId;
_fileIndex = _next->_fileIndex;
_linenr = _next->_linenr;
@ -223,7 +229,10 @@ void Token::deleteThis()
_isStandardType = _previous->_isStandardType;
_isExpandedMacro = _previous->_isExpandedMacro;
_isAttributeConstructor = _previous->_isAttributeConstructor;
_isAttributeDestructor = _previous->_isAttributeDestructor;
_isAttributeUnused = _previous->_isAttributeUnused;
_isAttributePure = _previous->_isAttributePure;
_isAttributeConst = _previous->_isAttributeConst;
_varId = _previous->_varId;
_fileIndex = _previous->_fileIndex;
_linenr = _previous->_linenr;

View File

@ -281,12 +281,30 @@ public:
void isAttributeConstructor(bool ac) {
_isAttributeConstructor = ac;
}
bool isAttributeDestructor() const {
return _isAttributeDestructor;
}
void isAttributeDestructor(bool value) {
_isAttributeDestructor = value;
}
bool isAttributeUnused() const {
return _isAttributeUnused;
}
void isAttributeUnused(bool unused) {
_isAttributeUnused = unused;
}
bool isAttributePure() const {
return _isAttributePure;
}
void isAttributePure(bool value) {
_isAttributePure = value;
}
bool isAttributeConst() const {
return _isAttributeConst;
}
void isAttributeConst(bool value) {
_isAttributeConst = value;
}
static const Token *findsimplematch(const Token *tok, const char pattern[]);
static const Token *findsimplematch(const Token *tok, const char pattern[], const Token *end);
@ -661,8 +679,11 @@ private:
bool _isLong;
bool _isStandardType;
bool _isExpandedMacro;
bool _isAttributeConstructor; // __attribute__((constructor))
bool _isAttributeConstructor; // __attribute__((constructor)) __attribute__((constructor(priority)))
bool _isAttributeDestructor; // __attribute__((destructor)) __attribute__((destructor(priority)))
bool _isAttributeUnused; // __attribute__((unused))
bool _isAttributePure; // __attribute__((pure))
bool _isAttributeConst; // __attribute__((const))
/** Updates internal property cache like _isName or _isBoolean.
Called after any _str() modification. */

View File

@ -116,7 +116,10 @@ Token *Tokenizer::copyTokens(Token *dest, const Token *first, const Token *last,
tok2->isLong(tok->isLong());
tok2->isExpandedMacro(tok->isExpandedMacro());
tok2->isAttributeConstructor(tok->isAttributeConstructor());
tok2->isAttributeDestructor(tok->isAttributeDestructor());
tok2->isAttributeUnused(tok->isAttributeUnused());
tok2->isAttributePure(tok->isAttributePure());
tok2->isAttributeConst(tok->isAttributeConst());
tok2->varId(tok->varId());
// Check for links and fix them up
@ -9089,8 +9092,24 @@ void Tokenizer::simplifyAttribute()
{
for (Token *tok = list.front(); tok; tok = tok->next()) {
while (Token::simpleMatch(tok, "__attribute__ (") && tok->next()->link() && tok->next()->link()->next()) {
if (Token::simpleMatch(tok->tokAt(2), "( constructor )")) {
tok->next()->link()->next()->isAttributeConstructor(true);
if (Token::simpleMatch(tok->tokAt(2), "( constructor")) {
// prototype for constructor is: void func(void);
if (tok->next()->link()->next()->str() == "void") // __attribute__((constructor)) void func() {}
tok->next()->link()->next()->next()->isAttributeConstructor(true);
else if (tok->next()->link()->next()->str() == ";") // void func() __attribute__((constructor));
tok->previous()->link()->previous()->isAttributeConstructor(true);
else // void __attribute__((constructor)) func() {}
tok->next()->link()->next()->isAttributeConstructor(true);
}
if (Token::simpleMatch(tok->tokAt(2), "( destructor")) {
// prototype for destructor is: void func(void);
if (tok->next()->link()->next()->str() == "void") // __attribute__((destructor)) void func() {}
tok->next()->link()->next()->next()->isAttributeDestructor(true);
else if (tok->next()->link()->next()->str() == ";") // void func() __attribute__((destructor));
tok->previous()->link()->previous()->isAttributeDestructor(true);
else // void __attribute__((destructor)) func() {}
tok->next()->link()->next()->isAttributeDestructor(true);
}
if (Token::simpleMatch(tok->tokAt(2), "( unused )")) {
@ -9105,6 +9124,16 @@ void Tokenizer::simplifyAttribute()
tok->next()->link()->next()->isAttributeUnused(true);
}
// type func(...) __attribute__((pure));
if (Token::simpleMatch(tok->tokAt(2), "( pure )")) {
tok->previous()->link()->previous()->isAttributePure(true);
}
// type func(...) __attribute__((const));
if (Token::simpleMatch(tok->tokAt(2), "( const )")) {
tok->previous()->link()->previous()->isAttributeConst(true);
}
Token::eraseTokens(tok, tok->next()->link()->next());
tok->deleteThis();
}

View File

@ -142,7 +142,11 @@ void TokenList::addtoken(const Token * tok, const unsigned int lineno, const uns
_back->isUnsigned(tok->isUnsigned());
_back->isSigned(tok->isSigned());
_back->isLong(tok->isLong());
_back->isAttributeConstructor(tok->isAttributeConstructor());
_back->isAttributeDestructor(tok->isAttributeDestructor());
_back->isAttributeUnused(tok->isAttributeUnused());
_back->isAttributePure(tok->isAttributePure());
_back->isAttributeConst(tok->isAttributeConst());
}
//---------------------------------------------------------------------------
// InsertTokens - Copy and insert tokens
@ -172,7 +176,11 @@ void TokenList::insertTokens(Token *dest, const Token *src, unsigned int n)
dest->isSigned(src->isSigned());
dest->isPointerCompare(src->isPointerCompare());
dest->isLong(src->isLong());
dest->isAttributeConstructor(src->isAttributeConstructor());
dest->isAttributeDestructor(src->isAttributeDestructor());
dest->isAttributeUnused(src->isAttributeUnused());
dest->isAttributePure(src->isAttributePure());
dest->isAttributeConst(src->isAttributeConst());
src = src->next();
--n;
}