Partial fix for #5555. Remember function attributes: pure, const, constructor, destructor
This commit is contained in:
parent
5698f7b337
commit
8c993c1363
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
23
lib/token.h
23
lib/token.h
|
@ -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. */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue