Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp

Issue 2616213003: Get more consistent decisions if a statement is constant in templates (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Changes Blink-style names to Chrome-style names. Currently transforms: 5 // Changes Blink-style names to Chrome-style names. Currently transforms:
6 // fields: 6 // fields:
7 // int m_operationCount => int operation_count_ 7 // int m_operationCount => int operation_count_
8 // variables (including parameters): 8 // variables (including parameters):
9 // int mySuperVariable => int my_super_variable 9 // int mySuperVariable => int my_super_variable
10 // constants: 10 // constants:
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 if (!first_char && was_lowercase && is_uppercase) 360 if (!first_char && was_lowercase && is_uppercase)
361 needs_underscore = true; 361 needs_underscore = true;
362 was_lowercase = is_lowercase; 362 was_lowercase = is_lowercase;
363 was_uppercase = is_uppercase; 363 was_uppercase = is_uppercase;
364 first_char = false; 364 first_char = false;
365 } 365 }
366 std::reverse(output.begin(), output.end()); 366 std::reverse(output.begin(), output.end());
367 return output; 367 return output;
368 } 368 }
369 369
370 bool CanBeEvaluatedAtCompileTime(const clang::Stmt* stmt,
371 const clang::ASTContext& context) {
372 auto* expr = clang::dyn_cast<clang::Expr>(stmt);
373 if (!expr) {
374 // If the statement is not an expression then it's a constant.
dcheng 2017/01/07 00:45:49 What would it be that makes it a constant?
danakj 2017/01/07 00:48:00 switch, if, return, language stuff. Not things tha
dcheng 2017/01/07 00:50:18 I think we always pass in an Expr though, no? So t
danakj 2017/01/09 16:01:33 Children of the expr are stmts though.
375 return true;
376 }
377
378 // Function calls create non-consistent behaviour. For some template
379 // instantiations they can be constexpr while for others they are not, which
380 // changes the output of isEvaluatable().
381 if (expr->hasNonTrivialCall(context))
382 return false;
383
384 // Recurse on children. If they are all const (or are uses of template
385 // input) then the statement can be considered const. For whatever reason the
386 // below checks can give different-and-less-consistent responses if we call
387 // them on a complex expression than if we call them on the most primitive
388 // pieces (some pieces would say false but the whole thing says true).
389 for (auto* child : expr->children()) {
390 if (!CanBeEvaluatedAtCompileTime(child, context))
danakj 2017/01/09 16:01:51 IE here child is not an expr always.
391 return false;
392 }
393
394 // If the expression is a template input then its coming at compile time so
395 // we consider it const. And we can't check isEvaluatable() in this case as
396 // it will do bad things/crash.
397 if (expr->isInstantiationDependent())
398 return true;
399
400 // If the expression can be evaluated at compile time, then it should have a
401 // kFoo style name. Otherwise, not.
402 return expr->isEvaluatable(context);
403 }
404
370 bool IsProbablyConst(const clang::VarDecl& decl, 405 bool IsProbablyConst(const clang::VarDecl& decl,
371 const clang::ASTContext& context) { 406 const clang::ASTContext& context) {
372 clang::QualType type = decl.getType(); 407 clang::QualType type = decl.getType();
373 if (!type.isConstQualified()) 408 if (!type.isConstQualified())
374 return false; 409 return false;
375 410
376 if (type.isVolatileQualified()) 411 if (type.isVolatileQualified())
377 return false; 412 return false;
378 413
379 // Parameters should not be renamed to |kFooBar| style (even if they are 414 // Parameters should not be renamed to |kFooBar| style (even if they are
380 // const and have an initializer (aka default value)). 415 // const and have an initializer (aka default value)).
381 if (clang::isa<clang::ParmVarDecl>(&decl)) 416 if (clang::isa<clang::ParmVarDecl>(&decl))
382 return false; 417 return false;
383 418
384 // http://google.github.io/styleguide/cppguide.html#Constant_Names 419 // http://google.github.io/styleguide/cppguide.html#Constant_Names
385 // Static variables that are const-qualified should use kConstantStyle naming. 420 // Static variables that are const-qualified should use kConstantStyle naming.
386 if (decl.getStorageDuration() == clang::SD_Static) 421 if (decl.getStorageDuration() == clang::SD_Static)
387 return true; 422 return true;
388 423
389 const clang::Expr* initializer = decl.getInit(); 424 const clang::Expr* initializer = decl.getInit();
390 if (!initializer) 425 if (!initializer)
391 return false; 426 return false;
392 427
393 // If the expression is dependent on a template input, then we are not 428 return CanBeEvaluatedAtCompileTime(initializer, context);
394 // sure if it can be compile-time generated as calling isEvaluatable() is
395 // not valid on |initializer|.
396 // TODO(crbug.com/581218): We could probably look at each compiled
397 // instantiation of the template and see if they are all compile-time
398 // isEvaluable().
399 if (initializer->isInstantiationDependent())
400 return false;
401
402 // If the expression can be evaluated at compile time, then it should have a
403 // kFoo style name. Otherwise, not.
404 return initializer->isEvaluatable(context);
405 } 429 }
406 430
407 AST_MATCHER_P(clang::QualType, hasString, std::string, ExpectedString) { 431 AST_MATCHER_P(clang::QualType, hasString, std::string, ExpectedString) {
408 return ExpectedString == Node.getAsString(); 432 return ExpectedString == Node.getAsString();
409 } 433 }
410 434
411 bool ShouldPrefixFunctionName(const std::string& old_method_name) { 435 bool ShouldPrefixFunctionName(const std::string& old_method_name) {
412 // Functions that are named similarily to a type - they should be prefixed 436 // Functions that are named similarily to a type - they should be prefixed
413 // with a "Get" prefix. 437 // with a "Get" prefix.
414 static const char* kConflictingMethods[] = { 438 static const char* kConflictingMethods[] = {
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix)); 644 original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix));
621 else if (original_name.startswith(kBlinkFieldPrefix)) 645 else if (original_name.startswith(kBlinkFieldPrefix))
622 original_name = original_name.substr(strlen(kBlinkFieldPrefix)); 646 original_name = original_name.substr(strlen(kBlinkFieldPrefix));
623 647
624 bool is_const = IsProbablyConst(decl, context); 648 bool is_const = IsProbablyConst(decl, context);
625 if (is_const) { 649 if (is_const) {
626 // Don't try to rename constants that already conform to Chrome style. 650 // Don't try to rename constants that already conform to Chrome style.
627 if (original_name.size() >= 2 && original_name[0] == 'k' && 651 if (original_name.size() >= 2 && original_name[0] == 'k' &&
628 clang::isUppercase(original_name[1])) 652 clang::isUppercase(original_name[1]))
629 return false; 653 return false;
654 // Or names are spelt with underscore casing. While they are actually
655 // compile consts, the author wrote it explicitly as a variable not as
656 // a constant (they would have used kFormat otherwise here), so preserve
657 // it rather than try to mangle a kFormat out of it.
658 if (original_name.find('_') != StringRef::npos)
659 return false;
630 660
631 name = 'k'; 661 name = 'k';
632 name.append(original_name.data(), original_name.size()); 662 name.append(original_name.data(), original_name.size());
633 name[1] = clang::toUppercase(name[1]); 663 name[1] = clang::toUppercase(name[1]);
634 } else { 664 } else {
635 name = CamelCaseToUnderscoreCase(original_name); 665 name = CamelCaseToUnderscoreCase(original_name);
636 666
637 // Non-const variables with static storage duration at namespace scope are 667 // Non-const variables with static storage duration at namespace scope are
638 // prefixed with `g_' to reduce the likelihood of a naming collision. 668 // prefixed with `g_' to reduce the likelihood of a naming collision.
639 const clang::DeclContext* decl_context = decl.getDeclContext(); 669 const clang::DeclContext* decl_context = decl.getDeclContext();
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 for (const auto& r : replacements) { 1487 for (const auto& r : replacements) {
1458 std::string replacement_text = r.getReplacementText().str(); 1488 std::string replacement_text = r.getReplacementText().str();
1459 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); 1489 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
1460 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() 1490 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
1461 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; 1491 << ":::" << r.getLength() << ":::" << replacement_text << "\n";
1462 } 1492 }
1463 llvm::outs() << "==== END EDITS ====\n"; 1493 llvm::outs() << "==== END EDITS ====\n";
1464 1494
1465 return 0; 1495 return 0;
1466 } 1496 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698