summaryrefslogtreecommitdiffstats
path: root/tools/gn/visual_studio_utils.cc
blob: 894472213dcf5102c74a3c3fa522fdba76945b94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/gn/visual_studio_utils.h"

#include "base/md5.h"
#include "base/strings/string_util.h"

CompilerOptions::CompilerOptions() = default;

CompilerOptions::~CompilerOptions() = default;

std::string MakeGuid(const std::string& entry_path, const std::string& seed) {
  std::string str = base::ToUpperASCII(base::MD5String(seed + entry_path));
  return '{' + str.substr(0, 8) + '-' + str.substr(8, 4) + '-' +
         str.substr(12, 4) + '-' + str.substr(16, 4) + '-' +
         str.substr(20, 12) + '}';
}

#define SetOption(condition, member, value) \
  if (condition) {                          \
    options->member = value;                \
    return;                                 \
  }

#define AppendOption(condition, member, value, separator) \
  if (condition) {                                        \
    options->member += value + separator;                 \
    return;                                               \
  }

void ParseCompilerOption(const std::string& cflag, CompilerOptions* options) {
  if (cflag.size() > 2 && cflag[0] == '/') {
    switch (cflag[1]) {
      case 'F':
        AppendOption(cflag.size() > 3 && cflag[2] == 'I', forced_include_files,
                     cflag.substr(3), ';')
        break;

      case 'G':
        if (cflag[2] == 'S') {
          SetOption(cflag.size() == 3, buffer_security_check, "true")
          SetOption(cflag.size() == 4 && cflag[3] == '-',
                    buffer_security_check, "false")
        }
        break;

      case 'M':
        switch (cflag[2]) {
          case 'D':
            SetOption(cflag.size() == 3, runtime_library, "MultiThreadedDLL")
            SetOption(cflag.size() == 4 && cflag[3] == 'd', runtime_library,
                      "MultiThreadedDebugDLL")
            break;

          case 'T':
            SetOption(cflag.size() == 3, runtime_library, "MultiThreaded")
            SetOption(cflag.size() == 4 && cflag[3] == 'd', runtime_library,
                      "MultiThreadedDebug")
            break;
        }
        break;

      case 'O':
        switch (cflag[2]) {
          case '1':
            SetOption(cflag.size() == 3, optimization, "MinSpace")
            break;

          case '2':
            SetOption(cflag.size() == 3, optimization, "MaxSpeed")
            break;

          case 'd':
            SetOption(cflag.size() == 3, optimization, "Disabled")
            break;

          case 'x':
            SetOption(cflag.size() == 3, optimization, "Full")
              break;
        }
        break;

      case 'T':
        // Skip flags that cause treating all source files as C and C++ files.
        if (cflag.size() == 3 && (cflag[2] == 'C' || cflag[2] == 'P'))
          return;
        break;

      case 'W':
        switch (cflag[2]) {
          case '0':
          case '1':
          case '2':
          case '3':
          case '4':
            SetOption(cflag.size() == 3, warning_level,
                      std::string("Level") + cflag[2])
            break;

          case 'X':
            SetOption(cflag.size() == 3, treat_warning_as_error, "true")
            break;
        }
        break;

      case 'w':
        AppendOption(cflag.size() > 3 && cflag[2] == 'd',
                     disable_specific_warnings, cflag.substr(3), ';')
        break;
    }
  }

  // Put everything else into additional_options.
  options->additional_options += cflag + ' ';
}