Fixed #5119 (Preprocessor: Using -D suppresses __cplusplus for C++ files)

This commit is contained in:
Daniel Marjamäki 2013-11-15 19:21:21 +01:00
parent 30720affd6
commit 8c7e3d14aa
3 changed files with 29 additions and 7 deletions

View File

@ -123,10 +123,18 @@ static std::string unify(const std::string &s, char separator)
} }
bool Preprocessor::cplusplus(const Settings *settings, const std::string &filename)
{
const bool undef = settings && settings->userUndefs.find("__cplusplus") != settings->userUndefs.end();
const bool cpplang = settings && settings->enforcedLang == Settings::CPP;
const bool cppfile = (!settings || settings->enforcedLang == Settings::None) && Path::isCPP(filename);
return (!undef && (cpplang || cppfile));
}
/** /**
* Get cfgmap - a map of macro names and values * Get cfgmap - a map of macro names and values
*/ */
static std::map<std::string,std::string> getcfgmap(const std::string &cfg) static std::map<std::string,std::string> getcfgmap(const std::string &cfg, const Settings *settings, const std::string &filename)
{ {
std::map<std::string, std::string> cfgmap; std::map<std::string, std::string> cfgmap;
@ -154,6 +162,9 @@ static std::map<std::string,std::string> getcfgmap(const std::string &cfg)
} }
} }
if (cfgmap.find("__cplusplus") == cfgmap.end() && Preprocessor::cplusplus(settings,filename))
cfgmap["__cplusplus"] = "1";
return cfgmap; return cfgmap;
} }
@ -1023,7 +1034,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
processedFile = ostr.str(); processedFile = ostr.str();
} }
std::map<std::string, std::string> defs(getcfgmap(_settings ? _settings->userDefines : std::string(""))); std::map<std::string, std::string> defs(getcfgmap(_settings ? _settings->userDefines : std::string(""), _settings, filename));
if (_settings && _settings->_maxConfigs == 1U) { if (_settings && _settings->_maxConfigs == 1U) {
std::set<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
@ -1735,9 +1746,7 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string
std::list<bool> matched_ifdef; std::list<bool> matched_ifdef;
// Create a map for the cfg for faster access to defines // Create a map for the cfg for faster access to defines
std::map<std::string, std::string> cfgmap(getcfgmap(cfg)); std::map<std::string, std::string> cfgmap(getcfgmap(cfg, _settings, filename));
if (((_settings && _settings->enforcedLang == Settings::CPP) || ((!_settings || _settings->enforcedLang == Settings::None) && Path::isCPP(filename))) && cfgmap.find("__cplusplus") == cfgmap.end())
cfgmap["__cplusplus"] = "1";
std::stack<std::string> filenames; std::stack<std::string> filenames;
filenames.push(filename); filenames.push(filename);
@ -2895,7 +2904,7 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file
{ {
// fill up "macros" with user defined macros // fill up "macros" with user defined macros
const std::map<std::string,std::string> cfgmap(getcfgmap(cfg)); const std::map<std::string,std::string> cfgmap(getcfgmap(cfg,NULL,""));
std::map<std::string, std::string>::const_iterator it; std::map<std::string, std::string>::const_iterator it;
for (it = cfgmap.begin(); it != cfgmap.end(); ++it) { for (it = cfgmap.begin(); it != cfgmap.end(); ++it) {
std::string s = it->first; std::string s = it->first;

View File

@ -96,6 +96,9 @@ public:
/** read preprocessor statements into a string. */ /** read preprocessor statements into a string. */
std::string readpreprocessor(std::istream &istr, const unsigned int bom) const; std::string readpreprocessor(std::istream &istr, const unsigned int bom) const;
/** should __cplusplus be defined? */
static bool cplusplus(const Settings *settings, const std::string &filename);
/** /**
* Get preprocessed code for a given configuration * Get preprocessed code for a given configuration
* @param filedata file data including preprocessing 'if', 'define', etc * @param filedata file data including preprocessing 'if', 'define', etc

View File

@ -3272,11 +3272,21 @@ private:
ASSERT_EQUALS("char buf[$123];\n", actual); ASSERT_EQUALS("char buf[$123];\n", actual);
} }
void predefine5() { // #3737 - automatically define __cplusplus void predefine5() { // #3737, #5119 - automatically define __cplusplus
// #3737...
const char code[] = "#ifdef __cplusplus\n123\n#endif"; const char code[] = "#ifdef __cplusplus\n123\n#endif";
Preprocessor preprocessor(NULL,this); Preprocessor preprocessor(NULL,this);
ASSERT_EQUALS("\n\n\n", preprocessor.getcode(code, "X=123", "test.c")); ASSERT_EQUALS("\n\n\n", preprocessor.getcode(code, "X=123", "test.c"));
ASSERT_EQUALS("\n123\n\n", preprocessor.getcode(code, "X=123", "test.cpp")); ASSERT_EQUALS("\n123\n\n", preprocessor.getcode(code, "X=123", "test.cpp"));
// #5119...
ASSERT_EQUALS(false, Preprocessor::cplusplus(NULL,"test.c"));
ASSERT_EQUALS(true, Preprocessor::cplusplus(NULL,"test.cpp"));
Settings settings;
ASSERT_EQUALS(true, Preprocessor::cplusplus(&settings,"test.cpp"));
settings.userUndefs.insert("__cplusplus");
ASSERT_EQUALS(false, Preprocessor::cplusplus(&settings,"test.cpp"));
} }
void predefine6() { // #3737 - using -D and -f => check all matching configurations void predefine6() { // #3737 - using -D and -f => check all matching configurations