stephanemoore marked 2 inline comments as done.
stephanemoore added inline comments.


================
Comment at: clang-tidy/google/FunctionNamingCheck.cpp:96-97
 
   // Match function declarations that are not in system headers and are not
   // main.
   Finder->addMatcher(
----------------
aaron.ballman wrote:
> This comment is drifting more and more out of sync with the code.
Good catch; updated the comment.


================
Comment at: test/clang-tidy/google-objc-function-naming.m:5-8
+static void TestImplicitlyDefinedFunction(int a) {
+  printf("%d", a);
+}
+
----------------
aaron.ballman wrote:
> Excuse my ignorance, but I don't see what about this function definition is 
> testing an implicitly-defined function. Doesn't the `#import` above bring in 
> the declaration for `printf()`, while `TestImplicitlyDefinedFunction()` 
> itself is explicitly defined?
**tl;dr**: Yes, we have an explicit function declaration but clang generates an 
implicit function declaration as well.

I found this surprising as well but the AST generated from this includes an 
implicit function declaration. Even though we have an explicit function 
declaration for `printf` from <stdio.h>, clang still generates an implicit 
declaration of `printf` ๐Ÿคจ Similar behavior occurs with other functions, e.g., 
`memset` and various C11 atomic functions.

I have been spelunking in search of the reason but I do not have a full 
understanding yet. I believe I have insight into the underlying mechanism 
though: the behavior seems linked to builtin functions (e.g., `printf` is 
declared as a builtin function 
[here](https://github.com/llvm/llvm-project/blob/2946cd7/clang/include/clang/Basic/Builtins.def#L889)).
 I have attached a small sample program and an associated AST dump below to 
demonstrate the behavior.

โง

```
$ cat /tmp/test.c
extern int printf(const char *format, ...);

int main(int argc, const char **argv) {
  printf("%d", argc);
  return 0;
}
```

```
$ clang -cc1 -ast-dump /tmp/test.c 
TranslationUnitDecl 0x561b9f7fe570 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x561b9f7feac0 <<invalid sloc>> <invalid sloc> implicit 
__int128_t '__int128'
| `-BuiltinType 0x561b9f7fe7e0 '__int128'
|-TypedefDecl 0x561b9f7feb28 <<invalid sloc>> <invalid sloc> implicit 
__uint128_t 'unsigned __int128'
| `-BuiltinType 0x561b9f7fe800 'unsigned __int128'
|-TypedefDecl 0x561b9f7fedf8 <<invalid sloc>> <invalid sloc> implicit 
__NSConstantString 'struct __NSConstantString_tag'
| `-RecordType 0x561b9f7fec00 'struct __NSConstantString_tag'
|   `-Record 0x561b9f7feb78 '__NSConstantString_tag'
|-TypedefDecl 0x561b9f7fee90 <<invalid sloc>> <invalid sloc> implicit 
__builtin_ms_va_list 'char *'
| `-PointerType 0x561b9f7fee50 'char *'
|   `-BuiltinType 0x561b9f7fe600 'char'
|-TypedefDecl 0x561b9f7ff158 <<invalid sloc>> <invalid sloc> implicit 
__builtin_va_list 'struct __va_list_tag [1]'
| `-ConstantArrayType 0x561b9f7ff100 'struct __va_list_tag [1]' 1 
|   `-RecordType 0x561b9f7fef70 'struct __va_list_tag'
|     `-Record 0x561b9f7feee0 '__va_list_tag'
|-FunctionDecl 0x561b9f851860 </tmp/test.c:1:12> col:12 implicit used printf 
'int (const char *, ...)' extern
| |-ParmVarDecl 0x561b9f8518f8 <<invalid sloc>> <invalid sloc> 'const char *'
| `-FormatAttr 0x561b9f851960 <col:12> Implicit printf 1 2
|-FunctionDecl 0x561b9f8519b8 prev 0x561b9f851860 <col:1, col:42> col:12 used 
printf 'int (const char *, ...)' extern
| |-ParmVarDecl 0x561b9f7ff1c0 <col:19, col:31> col:31 format 'const char *'
| `-FormatAttr 0x561b9f851a90 <col:12> Inherited printf 1 2
`-FunctionDecl 0x561b9f851c48 <line:3:1, line:6:1> line:3:5 main 'int (int, 
const char **)'
  |-ParmVarDecl 0x561b9f851ac8 <col:10, col:14> col:14 used argc 'int'
  |-ParmVarDecl 0x561b9f851b70 <col:20, col:33> col:33 argv 'const char **'
  `-CompoundStmt 0x561b9f851f08 <col:39, line:6:1>
    |-CallExpr 0x561b9f851e50 <line:4:3, col:20> 'int'
    | |-ImplicitCastExpr 0x561b9f851e38 <col:3> 'int (*)(const char *, ...)' 
<FunctionToPointerDecay>
    | | `-DeclRefExpr 0x561b9f851d58 <col:3> 'int (const char *, ...)' Function 
0x561b9f8519b8 'printf' 'int (const char *, ...)'
    | |-ImplicitCastExpr 0x561b9f851ea0 <col:10> 'const char *' <BitCast>
    | | `-ImplicitCastExpr 0x561b9f851e88 <col:10> 'char *' 
<ArrayToPointerDecay>
    | |   `-StringLiteral 0x561b9f851db8 <col:10> 'char [3]' lvalue "%d"
    | `-ImplicitCastExpr 0x561b9f851eb8 <col:16> 'int' <LValueToRValue>
    |   `-DeclRefExpr 0x561b9f851de8 <col:16> 'int' lvalue ParmVar 
0x561b9f851ac8 'argc' 'int'
    `-ReturnStmt 0x561b9f851ef0 <line:5:3, col:10>
      `-IntegerLiteral 0x561b9f851ed0 <col:10> 'int' 0
```

Note the presence of implicit and explicit declarations of `printf` in the AST 
dump ๐Ÿค”


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57207/new/

https://reviews.llvm.org/D57207



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to