1 /*
2 * Copyright (C) 2015, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "type_cpp.h"
18
19 #include <algorithm>
20 #include <iostream>
21 #include <vector>
22
23 #include <android-base/stringprintf.h>
24 #include <android-base/strings.h>
25
26 #include "logging.h"
27
28 using std::cerr;
29 using std::endl;
30 using std::set;
31 using std::string;
32 using std::unique_ptr;
33 using std::vector;
34
35 using android::base::Split;
36 using android::base::Join;
37 using android::base::StringPrintf;
38
39 namespace android {
40 namespace aidl {
41 namespace cpp {
42 namespace {
43
44 const char kNoPackage[] = "";
45 const char kNoHeader[] = "";
46 const char kNoValidMethod[] = "";
47 Type* const kNoArrayType = nullptr;
48 Type* const kNoNullableType = nullptr;
49
is_cpp_keyword(const std::string & str)50 bool is_cpp_keyword(const std::string& str) {
51 static const std::vector<std::string> kCppKeywords{
52 "alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor",
53 "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class",
54 "compl", "concept", "const", "constexpr", "const_cast", "continue",
55 "decltype", "default", "delete", "do", "double", "dynamic_cast", "else",
56 "enum", "explicit", "export", "extern", "false", "float", "for", "friend",
57 "goto", "if", "inline", "int", "long", "mutable", "namespace", "new",
58 "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
59 "private", "protected", "public", "register", "reinterpret_cast",
60 "requires", "return", "short", "signed", "sizeof", "static",
61 "static_assert", "static_cast", "struct", "switch", "template", "this",
62 "thread_local", "throw", "true", "try", "typedef", "typeid", "typename",
63 "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t",
64 "while", "xor", "xor_eq",
65 };
66 return std::find(kCppKeywords.begin(), kCppKeywords.end(), str) !=
67 kCppKeywords.end();
68 }
69
70 class VoidType : public Type {
71 public:
VoidType()72 VoidType() : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "void",
73 {}, "void", kNoValidMethod, kNoValidMethod) {}
74 virtual ~VoidType() = default;
CanBeOutParameter() const75 bool CanBeOutParameter() const override { return false; }
CanWriteToParcel() const76 bool CanWriteToParcel() const override { return false; }
77 }; // class VoidType
78
79 class CppArrayType : public Type {
80 public:
CppArrayType(int kind,const std::string & package,const string & underlying_aidl_type,const string & cpp_header,const string & underlying_cpp_type,const string & read_method,const string & write_method,bool is_nullable,const string & src_file_name="")81 CppArrayType(int kind, // from ValidatableType
82 const std::string& package,
83 const string& underlying_aidl_type,
84 const string& cpp_header,
85 const string& underlying_cpp_type,
86 const string& read_method,
87 const string& write_method,
88 bool is_nullable,
89 const string& src_file_name = "")
90 : Type(kind, package,
91 underlying_aidl_type + "[]",
92 GetHeaders(is_nullable, cpp_header),
93 GetCppType(is_nullable, underlying_cpp_type),
94 read_method, write_method, kNoArrayType,
95 (is_nullable)
96 ? kNoNullableType
97 // All arrays are nullable.
98 : new CppArrayType(kind, package, underlying_aidl_type,
99 cpp_header, underlying_cpp_type,
100 read_method, write_method, true),
101 src_file_name) {}
102
CanBeOutParameter() const103 bool CanBeOutParameter() const override { return true; }
104
105 private:
GetHeaders(bool is_nullable,const string & cpp_header)106 static vector<string> GetHeaders(bool is_nullable, const string& cpp_header) {
107 vector<string> result = {"vector"};
108 if (is_nullable) {
109 result.push_back("memory");
110 }
111 if (!cpp_header.empty()) {
112 result.push_back(cpp_header);
113 }
114 return result;
115 }
116
GetCppType(bool is_nullable,const string & underlying_cpp_type)117 static string GetCppType(bool is_nullable,
118 const string& underlying_cpp_type) {
119 if (is_nullable)
120 return StringPrintf("::std::unique_ptr<::std::vector<%s>>",
121 underlying_cpp_type.c_str());
122 return StringPrintf("::std::vector<%s>",
123 underlying_cpp_type.c_str());
124 }
125
126 DISALLOW_COPY_AND_ASSIGN(CppArrayType);
127 }; // class CppArrayType
128
129 class PrimitiveType : public Type {
130 public:
PrimitiveType(const std::string & aidl_type,const std::string & header,const std::string & cpp_type,const std::string & read_method,const std::string & write_method,const std::string & read_array_method,const std::string & write_array_method)131 PrimitiveType(const std::string& aidl_type,
132 const std::string& header,
133 const std::string& cpp_type,
134 const std::string& read_method,
135 const std::string& write_method,
136 const std::string& read_array_method,
137 const std::string& write_array_method)
138 : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, aidl_type, {header},
139 cpp_type, read_method, write_method,
140 new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
141 aidl_type, header, cpp_type,
142 read_array_method, write_array_method,
143 false)) {}
144
145 virtual ~PrimitiveType() = default;
IsCppPrimitive() const146 bool IsCppPrimitive() const override { return true; }
147
148 private:
149 DISALLOW_COPY_AND_ASSIGN(PrimitiveType);
150 }; // class PrimitiveType
151
152 // Unfortunately, bytes in Java are signed. However, most C authors would
153 // say that a byte is not in fact signed. Compromise: customize this otherwise
154 // normal primitive to use signed single bytes, but unsigned byte arrays.
155 class ByteType : public Type {
156 public:
ByteType()157 ByteType()
158 : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "byte",
159 {"cstdint"}, "int8_t", "readByte", "writeByte",
160 new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
161 "byte", "cstdint", "uint8_t",
162 "readByteVector", "writeByteVector",
163 false)) {}
164
165 virtual ~ByteType() = default;
IsCppPrimitive() const166 bool IsCppPrimitive() const override { return true; }
167
168 private:
169 DISALLOW_COPY_AND_ASSIGN(ByteType);
170 }; // class PrimitiveType
171
172 class BinderType : public Type {
173 public:
BinderType(const AidlInterface & interface,const std::string & src_file_name)174 BinderType(const AidlInterface& interface, const std::string& src_file_name)
175 : BinderType(interface, src_file_name,
176 new BinderType(interface, src_file_name, kNoNullableType,
177 "readNullableStrongBinder"),
178 "readStrongBinder") {}
179 virtual ~BinderType() = default;
180
WriteCast(const string & val) const181 string WriteCast(const string& val) const override {
182 return write_cast_ + "(" + val + ")";
183 }
184
185 private:
BinderType(const AidlInterface & interface,const std::string & src_file_name,Type * nullable_type,const std::string & read)186 BinderType(const AidlInterface& interface,
187 const std::string& src_file_name,
188 Type* nullable_type, const std::string& read)
189 : Type(ValidatableType::KIND_GENERATED,
190 interface.GetPackage(), interface.GetName(),
191 {GetCppHeader(interface)}, GetCppName(interface),
192 read, "writeStrongBinder", kNoArrayType, nullable_type,
193 src_file_name, interface.GetLine()),
194 write_cast_(GetRawCppName(interface) + "::asBinder") {}
195
GetCppName(const AidlInterface & interface)196 static string GetCppName(const AidlInterface& interface) {
197 return "::android::sp<" + GetRawCppName(interface) + ">";
198 }
199
GetRawCppName(const AidlInterface & interface)200 static string GetRawCppName(const AidlInterface& interface) {
201 vector<string> name = interface.GetSplitPackage();
202 string ret;
203
204 name.push_back(interface.GetName());
205
206 for (const auto& term : name) {
207 ret += "::" + term;
208 }
209
210 return ret;
211 }
212
GetCppHeader(const AidlInterface & interface)213 static string GetCppHeader(const AidlInterface& interface) {
214 vector<string> name = interface.GetSplitPackage();
215 name.push_back(interface.GetName());
216 return Join(name, '/') + ".h";
217 }
218
219 std::string write_cast_;
220 };
221
222 class NullableParcelableType : public Type {
223 public:
NullableParcelableType(const AidlParcelable & parcelable,const std::string & src_file_name)224 NullableParcelableType(const AidlParcelable& parcelable,
225 const std::string& src_file_name)
226 : Type(ValidatableType::KIND_PARCELABLE,
227 parcelable.GetPackage(), parcelable.GetName(),
228 {parcelable.GetCppHeader()}, GetCppName(parcelable),
229 "readParcelable", "writeNullableParcelable",
230 kNoArrayType, kNoNullableType,
231 src_file_name, parcelable.GetLine()) {}
232 virtual ~NullableParcelableType() = default;
CanBeOutParameter() const233 bool CanBeOutParameter() const override { return true; }
234
235 private:
GetCppName(const AidlParcelable & parcelable)236 static string GetCppName(const AidlParcelable& parcelable) {
237 return "::std::unique_ptr<::" + Join(parcelable.GetSplitPackage(), "::") +
238 "::" + parcelable.GetCppName() + ">";
239 }
240 };
241
242 class ParcelableType : public Type {
243 public:
ParcelableType(const AidlParcelable & parcelable,const std::string & src_file_name)244 ParcelableType(const AidlParcelable& parcelable,
245 const std::string& src_file_name)
246 : Type(ValidatableType::KIND_PARCELABLE,
247 parcelable.GetPackage(), parcelable.GetName(),
248 {parcelable.GetCppHeader()}, GetCppName(parcelable),
249 "readParcelable", "writeParcelable",
250 new CppArrayType(
251 ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(),
252 parcelable.GetName(), parcelable.GetCppHeader(),
253 GetCppName(parcelable),
254 "readParcelableVector", "writeParcelableVector", false,
255 src_file_name),
256 new NullableParcelableType(parcelable, src_file_name),
257 src_file_name, parcelable.GetLine()) {}
258 virtual ~ParcelableType() = default;
CanBeOutParameter() const259 bool CanBeOutParameter() const override { return true; }
260
261 private:
GetCppName(const AidlParcelable & parcelable)262 static string GetCppName(const AidlParcelable& parcelable) {
263 return "::" + Join(parcelable.GetSplitPackage(), "::") +
264 "::" + parcelable.GetCppName();
265 }
266 };
267
268 class NullableMap : public Type {
269 public:
NullableMap()270 NullableMap()
271 : Type(ValidatableType::KIND_BUILT_IN,
272 "java.util", "Map",
273 {"binder/Map.h", "binder/Value.h"},
274 "::std::unique_ptr<::android::binder::Map>",
275 "readNullableMap", "writeNullableMap") {}
276 virtual ~NullableMap() = default;
CanBeOutParameter() const277 bool CanBeOutParameter() const override { return true; }
278 };
279
280
281 class MapType : public Type {
282 public:
MapType()283 MapType()
284 : Type(ValidatableType::KIND_BUILT_IN,
285 "java.util", "Map",
286 {"binder/Map.h","binder/Value.h"},
287 "::android::binder::Map",
288 "readMap", "writeMap",
289 kNoArrayType,
290 new NullableMap() ) {}
291 virtual ~MapType() = default;
CanBeOutParameter() const292 bool CanBeOutParameter() const override { return true; }
293
294 private:
295 DISALLOW_COPY_AND_ASSIGN(MapType);
296 }; // class MapType
297
298 class NullableStringListType : public Type {
299 public:
NullableStringListType()300 NullableStringListType()
301 : Type(ValidatableType::KIND_BUILT_IN,
302 "java.util", "List<" + string(kStringCanonicalName) + ">",
303 {"utils/String16.h", "memory", "vector"},
304 "::std::unique_ptr<::std::vector<std::unique_ptr<::android::String16>>>",
305 "readString16Vector", "writeString16Vector") {}
306 virtual ~NullableStringListType() = default;
CanBeOutParameter() const307 bool CanBeOutParameter() const override { return true; }
308
309 private:
310 DISALLOW_COPY_AND_ASSIGN(NullableStringListType);
311 }; // class NullableStringListType
312
313 class StringListType : public Type {
314 public:
StringListType()315 StringListType()
316 : Type(ValidatableType::KIND_BUILT_IN,
317 "java.util", "List<" + string(kStringCanonicalName) + ">",
318 {"utils/String16.h", "vector"},
319 "::std::vector<::android::String16>",
320 "readString16Vector", "writeString16Vector",
321 kNoArrayType, new NullableStringListType()) {}
322 virtual ~StringListType() = default;
CanBeOutParameter() const323 bool CanBeOutParameter() const override { return true; }
324
325 private:
326 DISALLOW_COPY_AND_ASSIGN(StringListType);
327 }; // class StringListType
328
329 class NullableUtf8InCppStringListType : public Type {
330 public:
NullableUtf8InCppStringListType()331 NullableUtf8InCppStringListType()
332 : Type(ValidatableType::KIND_BUILT_IN,
333 "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
334 {"memory", "string", "vector"},
335 "::std::unique_ptr<::std::vector<std::unique_ptr<::std::string>>>",
336 "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector") {}
337 virtual ~NullableUtf8InCppStringListType() = default;
CanBeOutParameter() const338 bool CanBeOutParameter() const override { return true; }
339
340 private:
341 DISALLOW_COPY_AND_ASSIGN(NullableUtf8InCppStringListType);
342 }; // class NullableUtf8InCppStringListType
343
344 class Utf8InCppStringListType : public Type {
345 public:
Utf8InCppStringListType()346 Utf8InCppStringListType()
347 : Type(ValidatableType::KIND_BUILT_IN,
348 "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
349 {"string", "vector"},
350 "::std::vector<::std::string>",
351 "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
352 kNoArrayType, new NullableUtf8InCppStringListType()) {}
353 virtual ~Utf8InCppStringListType() = default;
CanBeOutParameter() const354 bool CanBeOutParameter() const override { return true; }
355
356 private:
357 DISALLOW_COPY_AND_ASSIGN(Utf8InCppStringListType);
358 }; // class Utf8InCppStringListType
359
360 class NullableBinderListType : public Type {
361 public:
NullableBinderListType()362 NullableBinderListType()
363 : Type(ValidatableType::KIND_BUILT_IN, "java.util",
364 "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
365 "::std::unique_ptr<::std::vector<::android::sp<::android::IBinder>>>",
366 "readStrongBinderVector", "writeStrongBinderVector") {}
367 virtual ~NullableBinderListType() = default;
CanBeOutParameter() const368 bool CanBeOutParameter() const override { return true; }
369
370 private:
371 DISALLOW_COPY_AND_ASSIGN(NullableBinderListType);
372 }; // class NullableBinderListType
373
374 class BinderListType : public Type {
375 public:
BinderListType()376 BinderListType()
377 : Type(ValidatableType::KIND_BUILT_IN, "java.util",
378 "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
379 "::std::vector<::android::sp<::android::IBinder>>",
380 "readStrongBinderVector", "writeStrongBinderVector",
381 kNoArrayType, new NullableBinderListType()) {}
382 virtual ~BinderListType() = default;
CanBeOutParameter() const383 bool CanBeOutParameter() const override { return true; }
384
385 private:
386 DISALLOW_COPY_AND_ASSIGN(BinderListType);
387 }; // class BinderListType
388
389 } // namespace
390
Type(int kind,const std::string & package,const std::string & aidl_type,const vector<string> & headers,const string & cpp_type,const string & read_method,const string & write_method,Type * array_type,Type * nullable_type,const string & src_file_name,int line)391 Type::Type(int kind,
392 const std::string& package,
393 const std::string& aidl_type,
394 const vector<string>& headers,
395 const string& cpp_type,
396 const string& read_method,
397 const string& write_method,
398 Type* array_type,
399 Type* nullable_type,
400 const string& src_file_name,
401 int line)
402 : ValidatableType(kind, package, aidl_type, src_file_name, line),
403 headers_(headers),
404 aidl_type_(aidl_type),
405 cpp_type_(cpp_type),
406 parcel_read_method_(read_method),
407 parcel_write_method_(write_method),
408 array_type_(array_type),
409 nullable_type_(nullable_type) {}
410
CanWriteToParcel() const411 bool Type::CanWriteToParcel() const { return true; }
412
Init()413 void TypeNamespace::Init() {
414 Add(new ByteType());
415 Add(new PrimitiveType(
416 "int",
417 "cstdint", "int32_t", "readInt32", "writeInt32",
418 "readInt32Vector", "writeInt32Vector"));
419 Add(new PrimitiveType(
420 "long",
421 "cstdint", "int64_t", "readInt64", "writeInt64",
422 "readInt64Vector", "writeInt64Vector"));
423 Add(new PrimitiveType(
424 "float",
425 kNoHeader, "float", "readFloat", "writeFloat",
426 "readFloatVector", "writeFloatVector"));
427 Add(new PrimitiveType(
428 "double",
429 kNoHeader, "double", "readDouble", "writeDouble",
430 "readDoubleVector", "writeDoubleVector"));
431 Add(new PrimitiveType(
432 "boolean",
433 kNoHeader, "bool", "readBool", "writeBool",
434 "readBoolVector", "writeBoolVector"));
435 // C++11 defines the char16_t type as a built in for Unicode characters.
436 Add(new PrimitiveType(
437 "char",
438 kNoHeader, "char16_t", "readChar", "writeChar",
439 "readCharVector", "writeCharVector"));
440
441 Type* string_array_type = new CppArrayType(
442 ValidatableType::KIND_BUILT_IN, "java.lang", "String",
443 "utils/String16.h", "::android::String16",
444 "readString16Vector", "writeString16Vector", false);
445
446 Type* nullable_string_type =
447 new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
448 {"memory", "utils/String16.h"}, "::std::unique_ptr<::android::String16>",
449 "readString16", "writeString16");
450
451 string_type_ = new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
452 {"utils/String16.h"}, "::android::String16",
453 "readString16", "writeString16",
454 string_array_type, nullable_string_type);
455 Add(string_type_);
456
457 using ::android::aidl::kAidlReservedTypePackage;
458 using ::android::aidl::kUtf8InCppStringClass;
459
460 // This type is a Utf16 string in the parcel, but deserializes to
461 // a std::string in Utf8 format when we use it in C++.
462 Type* cpp_utf8_string_array = new CppArrayType(
463 ValidatableType::KIND_BUILT_IN,
464 kAidlReservedTypePackage, kUtf8InCppStringClass,
465 "string", "::std::string",
466 "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
467 false);
468 Type* nullable_cpp_utf8_string_type = new Type(
469 ValidatableType::KIND_BUILT_IN,
470 kAidlReservedTypePackage, kUtf8InCppStringClass,
471 {"string", "memory"}, "::std::unique_ptr<::std::string>",
472 "readUtf8FromUtf16", "writeUtf8AsUtf16");
473 Add(new Type(
474 ValidatableType::KIND_BUILT_IN,
475 kAidlReservedTypePackage, kUtf8InCppStringClass,
476 {"string"}, "::std::string", "readUtf8FromUtf16", "writeUtf8AsUtf16",
477 cpp_utf8_string_array, nullable_cpp_utf8_string_type));
478
479 Type* nullable_ibinder = new Type(
480 ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
481 {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
482 "readNullableStrongBinder", "writeStrongBinder");
483 ibinder_type_ = new Type(
484 ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
485 {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
486 "readStrongBinder", "writeStrongBinder",
487 kNoArrayType, nullable_ibinder);
488 Add(ibinder_type_);
489
490 Add(new MapType());
491
492 Add(new BinderListType());
493 Add(new StringListType());
494 Add(new Utf8InCppStringListType());
495
496 Type* fd_vector_type = new CppArrayType(
497 ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
498 "android-base/unique_fd.h",
499 "::android::base::unique_fd",
500 "readUniqueFileDescriptorVector", "writeUniqueFileDescriptorVector",
501 false);
502
503 Add(new Type(
504 ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
505 {"android-base/unique_fd.h"}, "::android::base::unique_fd",
506 "readUniqueFileDescriptor", "writeUniqueFileDescriptor",
507 fd_vector_type));
508
509 void_type_ = new class VoidType();
510 Add(void_type_);
511 }
512
AddParcelableType(const AidlParcelable & p,const string & filename)513 bool TypeNamespace::AddParcelableType(const AidlParcelable& p,
514 const string& filename) {
515 if (p.GetCppHeader().empty()) {
516 LOG(ERROR) << "Parcelable " << p.GetCanonicalName()
517 << " has no C++ header defined.";
518 return false;
519 }
520 Add(new ParcelableType(p, filename));
521 return true;
522 }
523
AddBinderType(const AidlInterface & b,const string & file_name)524 bool TypeNamespace::AddBinderType(const AidlInterface& b,
525 const string& file_name) {
526 Add(new BinderType(b, file_name));
527 return true;
528 }
529
AddListType(const std::string & type_name)530 bool TypeNamespace::AddListType(const std::string& type_name) {
531 const Type* contained_type = FindTypeByCanonicalName(type_name);
532 if (!contained_type) {
533 LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
534 "type cannot be found or is invalid.";
535 return false;
536 }
537 if (contained_type->IsCppPrimitive()) {
538 LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
539 "type is a primitive in Java and Java List cannot hold "
540 "primitives.";
541 return false;
542 }
543
544 if (contained_type->CanonicalName() == kStringCanonicalName ||
545 contained_type->CanonicalName() == kUtf8InCppStringCanonicalName ||
546 contained_type == IBinderType()) {
547 return true;
548 }
549
550 // TODO Support lists of parcelables b/23600712
551
552 LOG(ERROR) << "aidl-cpp does not yet support List<" << type_name << ">";
553 return false;
554 }
555
AddMapType(const std::string &,const std::string &)556 bool TypeNamespace::AddMapType(const std::string& /* key_type_name */,
557 const std::string& /* value_type_name */) {
558 // TODO Support list types b/25242025
559 LOG(ERROR) << "aidl does not implement support for typed maps!";
560 return false;
561 }
562
IsValidPackage(const string & package) const563 bool TypeNamespace::IsValidPackage(const string& package) const {
564 if (package.empty()) {
565 return false;
566 }
567
568 auto pieces = Split(package, ".");
569 for (const string& piece : pieces) {
570 if (is_cpp_keyword(piece)) {
571 return false;
572 }
573 }
574
575 return true;
576 }
577
GetArgType(const AidlArgument & a,int arg_index,const std::string & filename,const AidlInterface & interface) const578 const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a,
579 int arg_index,
580 const std::string& filename,
581 const AidlInterface& interface) const {
582 const string error_prefix = StringPrintf(
583 "In file %s line %d parameter %s (%d):\n ",
584 filename.c_str(), a.GetLine(), a.GetName().c_str(), arg_index);
585
586 // check that the name doesn't match a keyword
587 if (is_cpp_keyword(a.GetName().c_str())) {
588 cerr << error_prefix << "Argument name is a C++ keyword"
589 << endl;
590 return nullptr;
591 }
592
593 return ::android::aidl::TypeNamespace::GetArgType(a, arg_index, filename,
594 interface);
595 }
596
597 } // namespace cpp
598 } // namespace aidl
599 } // namespace android
600